From 6c085218a3efc54509e7d5e250b3eb890483834a Mon Sep 17 00:00:00 2001 From: Fan YANG Date: Mon, 12 Aug 2024 16:53:02 +0800 Subject: [PATCH] [bsp][hpmicro][hpm6e00evk] add hpm6e00evk support - added hpm6e00evk support Signed-off-by: Fan YANG --- .github/workflows/bsp_buildings.yml | 1 + bsp/hpmicro/hpm6e00evk/.config | 1194 +++++++++ bsp/hpmicro/hpm6e00evk/Kconfig | 12 + bsp/hpmicro/hpm6e00evk/README.md | 115 + bsp/hpmicro/hpm6e00evk/README_zh.md | 114 + bsp/hpmicro/hpm6e00evk/SConscript | 17 + bsp/hpmicro/hpm6e00evk/SConstruct | 75 + .../hpm6e00evk/applications/SConscript | 14 + bsp/hpmicro/hpm6e00evk/applications/main.c | 43 + bsp/hpmicro/hpm6e00evk/board/Kconfig | 302 +++ bsp/hpmicro/hpm6e00evk/board/SConscript | 19 + bsp/hpmicro/hpm6e00evk/board/board.c | 1132 +++++++++ bsp/hpmicro/hpm6e00evk/board/board.h | 714 ++++++ .../openocd/boards/hpm6e00evk.cfg | 80 + .../openocd/probes/cmsis_dap.cfg | 11 + .../debug_scripts/openocd/probes/ft2232.cfg | 15 + .../debug_scripts/openocd/probes/ft232.cfg | 14 + .../debug_scripts/openocd/probes/jlink.cfg | 11 + .../openocd/probes/nds_aice_micro.cfg | 14 + .../openocd/soc/hpm6e80-dual-core.cfg | 63 + .../openocd/soc/hpm6e80-single-core.cfg | 18 + bsp/hpmicro/hpm6e00evk/board/fal_cfg.h | 49 + bsp/hpmicro/hpm6e00evk/board/fal_flash_port.c | 268 +++ bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.c | 543 +++++ bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.h | 227 ++ .../hpm6e00evk/board/hpm_wm8960_regs.h | 2139 +++++++++++++++++ .../board/linker_scripts/flash_rtt.ld | 297 +++ .../board/linker_scripts/flash_rtt_enet.ld | 316 +++ .../board/linker_scripts/ram_rtt.ld | 248 ++ bsp/hpmicro/hpm6e00evk/board/pinmux.c | 699 ++++++ bsp/hpmicro/hpm6e00evk/board/pinmux.h | 60 + bsp/hpmicro/hpm6e00evk/board/rtt_board.c | 131 + bsp/hpmicro/hpm6e00evk/board/rtt_board.h | 81 + bsp/hpmicro/hpm6e00evk/figures/board.png | Bin 0 -> 327780 bytes bsp/hpmicro/hpm6e00evk/rtconfig.h | 337 +++ bsp/hpmicro/hpm6e00evk/rtconfig.py | 110 + .../hpm6e00evk/startup/HPM6E80/SConscript | 19 + .../hpm6e00evk/startup/HPM6E80/startup.c | 128 + .../startup/HPM6E80/toolchains/gcc/port_gcc.S | 23 + .../startup/HPM6E80/toolchains/gcc/start.S | 92 + .../startup/HPM6E80/toolchains/gcc/vectors.S | 174 ++ bsp/hpmicro/hpm6e00evk/startup/HPM6E80/trap.c | 311 +++ bsp/hpmicro/hpm6e00evk/startup/SConscript | 13 + 43 files changed, 10243 insertions(+) create mode 100644 bsp/hpmicro/hpm6e00evk/.config create mode 100644 bsp/hpmicro/hpm6e00evk/Kconfig create mode 100644 bsp/hpmicro/hpm6e00evk/README.md create mode 100644 bsp/hpmicro/hpm6e00evk/README_zh.md create mode 100644 bsp/hpmicro/hpm6e00evk/SConscript create mode 100644 bsp/hpmicro/hpm6e00evk/SConstruct create mode 100644 bsp/hpmicro/hpm6e00evk/applications/SConscript create mode 100644 bsp/hpmicro/hpm6e00evk/applications/main.c create mode 100644 bsp/hpmicro/hpm6e00evk/board/Kconfig create mode 100644 bsp/hpmicro/hpm6e00evk/board/SConscript create mode 100644 bsp/hpmicro/hpm6e00evk/board/board.c create mode 100644 bsp/hpmicro/hpm6e00evk/board/board.h create mode 100644 bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/boards/hpm6e00evk.cfg create mode 100644 bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/cmsis_dap.cfg create mode 100644 bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/ft2232.cfg create mode 100644 bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/ft232.cfg create mode 100644 bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/jlink.cfg create mode 100644 bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/nds_aice_micro.cfg create mode 100644 bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/soc/hpm6e80-dual-core.cfg create mode 100644 bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/soc/hpm6e80-single-core.cfg create mode 100644 bsp/hpmicro/hpm6e00evk/board/fal_cfg.h create mode 100644 bsp/hpmicro/hpm6e00evk/board/fal_flash_port.c create mode 100644 bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.c create mode 100644 bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.h create mode 100644 bsp/hpmicro/hpm6e00evk/board/hpm_wm8960_regs.h create mode 100644 bsp/hpmicro/hpm6e00evk/board/linker_scripts/flash_rtt.ld create mode 100644 bsp/hpmicro/hpm6e00evk/board/linker_scripts/flash_rtt_enet.ld create mode 100644 bsp/hpmicro/hpm6e00evk/board/linker_scripts/ram_rtt.ld create mode 100644 bsp/hpmicro/hpm6e00evk/board/pinmux.c create mode 100644 bsp/hpmicro/hpm6e00evk/board/pinmux.h create mode 100644 bsp/hpmicro/hpm6e00evk/board/rtt_board.c create mode 100644 bsp/hpmicro/hpm6e00evk/board/rtt_board.h create mode 100644 bsp/hpmicro/hpm6e00evk/figures/board.png create mode 100644 bsp/hpmicro/hpm6e00evk/rtconfig.h create mode 100644 bsp/hpmicro/hpm6e00evk/rtconfig.py create mode 100644 bsp/hpmicro/hpm6e00evk/startup/HPM6E80/SConscript create mode 100644 bsp/hpmicro/hpm6e00evk/startup/HPM6E80/startup.c create mode 100644 bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/port_gcc.S create mode 100644 bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/start.S create mode 100644 bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/vectors.S create mode 100644 bsp/hpmicro/hpm6e00evk/startup/HPM6E80/trap.c create mode 100644 bsp/hpmicro/hpm6e00evk/startup/SConscript diff --git a/.github/workflows/bsp_buildings.yml b/.github/workflows/bsp_buildings.yml index 6c15807f67..26c8053f71 100644 --- a/.github/workflows/bsp_buildings.yml +++ b/.github/workflows/bsp_buildings.yml @@ -341,6 +341,7 @@ jobs: - "hpmicro/hpm5300evk" - "hpmicro/hpm5301evklite" - "hpmicro/hpm6800evk" + - "hpmicro/hpm6e00evk" - RTT_BSP: "llvm-arm" RTT_TOOL_CHAIN: "llvm-arm" SUB_RTT_BSP: diff --git a/bsp/hpmicro/hpm6e00evk/.config b/bsp/hpmicro/hpm6e00evk/.config new file mode 100644 index 0000000000..c4b6d48af8 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/.config @@ -0,0 +1,1194 @@ + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_NANO is not set +# CONFIG_RT_USING_AMP is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_CPUS_NR=1 +CONFIG_RT_ALIGN_SIZE=8 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +# CONFIG_RT_USING_HOOKLIST is not set +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=1024 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=1024 +# CONFIG_RT_USING_TIMER_ALL_SOFT is not set +# CONFIG_RT_USING_CPU_USAGE_TRACER is not set + +# +# kservice optimization +# +# CONFIG_RT_USING_TINY_FFS is not set +# end of kservice optimization + +# +# klibc optimization +# +# CONFIG_RT_KLIBC_USING_STDLIB is not set +# CONFIG_RT_KLIBC_USING_TINY_SIZE is not set +# CONFIG_RT_KLIBC_USING_PRINTF_LONGLONG is not set +# end of klibc optimization + +CONFIG_RT_USING_DEBUG=y +CONFIG_RT_DEBUGING_ASSERT=y +CONFIG_RT_DEBUGING_COLOR=y +CONFIG_RT_DEBUGING_CONTEXT=y +# CONFIG_RT_DEBUGING_AUTO_INIT is not set +CONFIG_RT_USING_OVERFLOW_CHECK=y + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY is not set +# CONFIG_RT_USING_SIGNALS is not set +# end of Inter-Thread communication + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y +# end of Memory Management + +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +# CONFIG_RT_USING_THREADSAFE_PRINTF is not set +# CONFIG_RT_USING_SCHED_THREAD_CTX is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" +CONFIG_RT_VER_NUM=0x50200 +# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 +# end of RT-Thread Kernel + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 +CONFIG_FINSH_USING_OPTION_COMPLETION=y + +# +# DFS: device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V1=y +# CONFIG_RT_USING_DFS_V2 is not set +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_CROMFS is not set +# CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_TMPFS is not set +# CONFIG_RT_USING_DFS_MQUEUE is not set +# end of DFS: device virtual file system + +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_DEV_BUS is not set +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +# CONFIG_RT_USING_NULL is not set +# CONFIG_RT_USING_ZERO is not set +# CONFIG_RT_USING_RANDOM is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_KTIME is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CHERRYUSB is not set +# end of Device Drivers + +# +# C/C++ and POSIX layer +# + +# +# ISO-ANSI C layer +# + +# +# Timezone and Daylight Saving Time +# +# CONFIG_RT_LIBC_USING_FULL_TZ_DST is not set +CONFIG_RT_LIBC_USING_LIGHT_TZ_DST=y +CONFIG_RT_LIBC_TZ_DEFAULT_HOUR=8 +CONFIG_RT_LIBC_TZ_DEFAULT_MIN=0 +CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0 +# end of Timezone and Daylight Saving Time +# end of ISO-ANSI C layer + +# +# POSIX (Portable Operating System Interface) layer +# +# CONFIG_RT_USING_POSIX_FS is not set +# CONFIG_RT_USING_POSIX_DELAY is not set +# CONFIG_RT_USING_POSIX_CLOCK is not set +# CONFIG_RT_USING_POSIX_TIMER is not set +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# end of Interprocess Communication (IPC) +# end of POSIX (Portable Operating System Interface) layer + +# CONFIG_RT_USING_CPLUSPLUS is not set +# end of C/C++ and POSIX layer + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set +# end of Network + +# +# Memory protection +# +# CONFIG_RT_USING_MEM_PROTECTION is not set +# CONFIG_RT_USING_HW_STACK_GUARD is not set +# end of Memory protection + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +# CONFIG_RT_USING_RESOURCE_ID is not set +# CONFIG_RT_USING_ADT is not set +# CONFIG_RT_USING_RT_LINK is not set +# end of Utilities + +# CONFIG_RT_USING_VBUS is not set + +# +# Using USB legacy version +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set +# end of Using USB legacy version + +# CONFIG_RT_USING_FDT is not set +# end of RT-Thread Components + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set +# end of RT-Thread Utestcases + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set +# CONFIG_PKG_USING_WIFI_HOST_DRIVER is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set +# end of Marvell WiFi + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# end of Wiced WiFi + +# CONFIG_PKG_USING_RW007 is not set + +# +# CYW43012 WiFi +# +# CONFIG_PKG_USING_WLAN_CYW43012 is not set +# end of CYW43012 WiFi + +# +# BL808 WiFi +# +# CONFIG_PKG_USING_WLAN_BL808 is not set +# end of BL808 WiFi + +# +# CYW43439 WiFi +# +# CONFIG_PKG_USING_WLAN_CYW43439 is not set +# end of CYW43439 WiFi +# end of Wi-Fi + +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# end of IoT Cloud + +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_BT_CYW43012 is not set +# CONFIG_PKG_USING_CYW43XX is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set +# CONFIG_PKG_USING_RYANW5500 is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set +# CONFIG_PKG_USING_ZEPHYR_POLLING is not set +# CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set +# CONFIG_PKG_USING_LHC_MODBUS is not set +# CONFIG_PKG_USING_QMODBUS is not set +# end of IoT - internet of things + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set +# end of security packages + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set +# end of JSON: JavaScript Object Notation, a lightweight data-interchange format + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# end of XML: Extensible Markup Language + +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set +# end of language packages + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set +# end of LVGL: powerful and easy-to-use embedded GUI library + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# end of u8g2: a monochrome graphic library + +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_3GPP_AMRNB is not set +# end of multimedia packages + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set +# CONFIG_PKG_USING_ZDEBUG is not set +# end of tools packages + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set +# end of enhanced kernel services + +# CONFIG_PKG_USING_AUNITY is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set +# end of acceleration: Assembly language or algorithmic acceleration packages + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_CORE is not set +# CONFIG_PKG_USING_CMSIS_DSP is not set +# CONFIG_PKG_USING_CMSIS_NN is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set +# end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# end of Micrium: Micrium software products porting for RT-Thread + +# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_LITEOS_SDK is not set +# CONFIG_PKG_USING_TZ_DATABASE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FILEX is not set +# CONFIG_PKG_USING_LEVELX is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_RPMSG_LITE is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set +# CONFIG_PKG_USING_FLASH_BLOB is not set +# CONFIG_PKG_USING_MLIBC is not set +# CONFIG_PKG_USING_TASK_MSG_BUS is not set +# CONFIG_PKG_USING_SFDB is not set +# CONFIG_PKG_USING_RTP is not set +# CONFIG_PKG_USING_REB is not set +# CONFIG_PKG_USING_R_RHEALSTONE is not set +# end of system packages + +# +# peripheral libraries and drivers +# + +# +# HAL & SDK Drivers +# + +# +# STM32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# end of STM32 HAL & SDK Drivers + +# +# Infineon HAL Packages +# +# CONFIG_PKG_USING_INFINEON_CAT1CM0P is not set +# CONFIG_PKG_USING_INFINEON_CMSIS is not set +# CONFIG_PKG_USING_INFINEON_CORE_LIB is not set +# CONFIG_PKG_USING_INFINEON_MTB_HAL_CAT1 is not set +# CONFIG_PKG_USING_INFINEON_MTB_PDL_CAT1 is not set +# CONFIG_PKG_USING_INFINEON_RETARGET_IO is not set +# CONFIG_PKG_USING_INFINEON_CAPSENSE is not set +# CONFIG_PKG_USING_INFINEON_CSDIDAC is not set +# CONFIG_PKG_USING_INFINEON_SERIAL_FLASH is not set +# CONFIG_PKG_USING_INFINEON_USBDEV is not set +# end of Infineon HAL Packages + +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_ESP_IDF is not set + +# +# Kendryte SDK +# +# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# end of Kendryte SDK + +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# end of HAL & SDK Drivers + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_SHT4X is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_STHS34PF80 is not set +# end of sensors drivers + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_CST816X is not set +# CONFIG_PKG_USING_CST812T is not set +# end of touch drivers + +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_ILI9341 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set +# CONFIG_PKG_USING_AIP650 is not set +# CONFIG_PKG_USING_FINGERPRINT is not set +# CONFIG_PKG_USING_BT_ECB02C is not set +# CONFIG_PKG_USING_UAT is not set +# CONFIG_PKG_USING_ST7789 is not set +# CONFIG_PKG_USING_VS1003 is not set +# CONFIG_PKG_USING_X9555 is not set +# CONFIG_PKG_USING_SYSTEM_RUN_LED is not set +# CONFIG_PKG_USING_BT_MX01 is not set +# CONFIG_PKG_USING_RGPOWER is not set +# CONFIG_PKG_USING_SPI_TOOLS is not set +# end of peripheral libraries and drivers + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set +# CONFIG_PKG_USING_R_TINYMAIX is not set +# end of AI packages + +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_APID is not set +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_QPID is not set +# CONFIG_PKG_USING_UKAL is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_KISSFFT is not set +# end of Signal Processing and Control Algorithm Packages + +# +# miscellaneous packages +# + +# +# project laboratory +# +# end of project laboratory + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# end of samples: kernel and components samples + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_MORSE is not set +# end of entertainment: terminal games and other interesting software packages + +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_RALARAM is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +# CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set +# end of miscellaneous packages + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects and Demos +# +# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set +# CONFIG_PKG_USING_ARDUINO_SKETCH_LOADER_DEMO is not set +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set +# end of Projects and Demos + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_JARZEBSKI_MPU6050 is not set +# end of Sensors + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_GFX_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_TFT_ESPI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ST7735 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SSD1306 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ILI9341 is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set +# end of Display + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set +# CONFIG_PKG_USING_ARDUINO_TICKER is not set +# CONFIG_PKG_USING_ARDUINO_TASKSCHEDULER is not set +# end of Timing + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set +# CONFIG_PKG_USING_ARDUINO_TENSORFLOW_LITE_MICRO is not set +# CONFIG_PKG_USING_ARDUINO_RUNNINGMEDIAN is not set +# end of Data Processing + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set +# end of Communication + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set +# end of Device Control + +# +# Other +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set +# end of Other + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set +# end of Signal IO + +# +# Uncategorized +# +# end of Arduino libraries +# end of RT-Thread online packages + +# +# Hardware Drivers Config +# +CONFIG_SOC_HPM6E00=y + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_GPIO=y +CONFIG_BSP_USING_UART=y +CONFIG_BSP_USING_UART0=y +# CONFIG_BSP_UART0_RX_USING_DMA is not set +# CONFIG_BSP_UART0_TX_USING_DMA is not set +# CONFIG_BSP_USING_UART1 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_RTC is not set +# CONFIG_BSP_USING_ETH is not set +# CONFIG_BSP_USING_GPTMR is not set +# CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_XPI_FLASH is not set +# CONFIG_BSP_USING_DAO is not set +# CONFIG_BSP_USING_PDM is not set +# CONFIG_BSP_USING_I2S is not set +# CONFIG_BSP_USING_USB is not set +# CONFIG_BSP_USING_EWDG is not set +# CONFIG_BSP_USING_PWMV2 is not set +# CONFIG_BSP_USING_MCAN is not set +# CONFIG_BSP_USING_ADC is not set +# end of On-chip Peripheral Drivers +# end of Hardware Drivers Config diff --git a/bsp/hpmicro/hpm6e00evk/Kconfig b/bsp/hpmicro/hpm6e00evk/Kconfig new file mode 100644 index 0000000000..73238d3a13 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/Kconfig @@ -0,0 +1,12 @@ +mainmenu "RT-Thread Configuration" + +BSP_DIR := . + +RTT_DIR := ../../.. + +PKGS_DIR := packages + +source "$(RTT_DIR)/Kconfig" +osource "$PKGS_DIR/Kconfig" +rsource "../libraries/Kconfig" +rsource "board/Kconfig" diff --git a/bsp/hpmicro/hpm6e00evk/README.md b/bsp/hpmicro/hpm6e00evk/README.md new file mode 100644 index 0000000000..d01a32f084 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/README.md @@ -0,0 +1,115 @@ +# HPMicro HPM6E00EVK BSP(Board Support Package) Introduction + +[中文页](README_zh.md) | + +## Introduction + +This document provides brief introduction of the BSP (board support package) for the HPM6E00EVK development board. + +The document consists of the following parts: + +- HPM6E00EVK Board Resources Introduction +- Quickly Getting Started +- Refreences + +By reading the Quickly Get Started section developers can quickly get their hands on this BSP and run RT-Thread on the board. More advanced features will be introduced in the Advanced Features section to help developers take advantage of RT-Thread to drive more on-board resources. + +## Board Resources Introduction + +HPM6E00EVK is a development board based on the RISC-V core launched by HPMicro, with rich on-board resources and on-chip resources for Connectivity, Audio, motor control,etc. +![board](figures/board.png) + + +## Peripheral Condition + +Each peripheral supporting condition for this BSP is as follows: + + +| **On-board Peripherals** | **Support** | **Note** | +| ------------------------ | ----------- | ------------------------------------- | +| USB | √ | | +| QSPI Flash | √ | | +| Ethernet | √ | | +| GPIO | √ | | +| SPI | √ | | +| I2C | √ | | +| RTC | √ | | +| PWM | √ | | +| On-Board Debugger | √ | ft2232 | + + +## Execution Instruction + +### Quickly Getting Started + +The BSP support being build via the 'scons' command, below is the steps of compiling the example via the 'scons' command + +#### Parpare Environment +- Step 1: Prepare [RT-Thread ENV](https://www.rt-thread.org/download.html#download-rt-thread-env-tool) +- Step 2: Prepare [toolcahin](https://github.com/helloeagleyang/riscv32-gnu-toolchain-win/archive/2022.04.12.zip) + - Download the package and extract it into a specified directory, for example: `C:\DevTools\riscv32-gnu-toolchain` +- Step 3: Set environment variable `RTT_RISCV_TOOLCHAIN` to `\bin` + - For example: `C:\DevTools\riscv32-gnu-toolchain\bin` +- Step 4: Prepare [OpenOCD](https://github.com/hpmicro/rtt-debugger-support-package/archive/v0.4.0.zip) + - Download and extract it to specified directory, for example: `C:\DevTools\openocd-hpmicro` + - Add `OpenOCD` environment variable `OPENOCD_HPMICRO` to `\bin` + - For example: `C:\DevTools\openocd-hpmicro\bin` + +#### Configure and Build project + +Open RT-Thread ENV command-line, and change directory to this BSP directory, then users can: + +- Configure the project via `menuconfig` in `RT-Thread ENV` +- Build the project using `scons -jN`, `N` equals to the number of CPU cores +- Clean the project using `scons -c` + +#### Hardware Connection + +- Switch BOOT pin to 2'b00 +- Connect the `PWR_DEBUG` port to PC via TYPE-C cable + + +#### Dowload / Debug + +- Users can download the project via the below command: + ```console + %OPENOCD_HPMICRO%\openocd.exe -f boards\debug_scripts\probes\ft2232.cfg -f boards\debug_scripts\soc\hpm6e80-single-core.cfg -f boards\debug_scripts\boards\hpm6e00evk.cfg -c "init; halt; flash write_image erase rtthread.elf; reset; shutdown" + ``` + +- Users can debug the project via the below command: + + - Connect debugger via `OpenOCD`: + +```console +%OPENOCD_HPMICRO%\openocd.exe -f boards\debug_scripts\probes\ft2232.cfg -f boards\debug_scripts\soc\hpm6e80-single-core.cfg -f boards\debug_scripts\boards\hpm6e00evk.cfg +``` + - Start Debugger via `GDB`: + +```console +%RTT_EXEC_PATH%\riscv32-unknown-elf-gdb.exe rtthread.elf +``` + - In the `gdb shell`, type the following commands: + +```console +load +c +``` + +### **Running Results** + +Once the project is successfully downloaded, the system runs automatically. The LED on the board will flash periodically. + +Connect the serial port of the board to the PC, communicate with it via a serial terminal tool(115200-8-1-N). Reset the board and the startup information of RT-Thread will be observed: + +``` + \ | / +- RT - Thread Operating System + / | \ 5.0.1 build Aug 16 2023 18:18:18 + 2006 - 2023 Copyright by RT-Thread team +``` + +## **References** + +- [RT-Thread Documnent Center](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/README) +- [RT-Thread Env](https://github.com/RT-Thread/rtthread-manual-doc/blob/master/env/env.md) +- [HPM6800EVK RT-Thread BSP Package](https://github.com/hpmicro/rtt-bsp-hpm6e00evk) \ No newline at end of file diff --git a/bsp/hpmicro/hpm6e00evk/README_zh.md b/bsp/hpmicro/hpm6e00evk/README_zh.md new file mode 100644 index 0000000000..9ac8ba5b46 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/README_zh.md @@ -0,0 +1,114 @@ +# 先楫 HPM6E00EVK BSP(板级支持包)说明 + +[English](README.md) | + +## 简介 + +本文档为 HPM6E00EVK 的 BSP (板级支持包) 说明。 + +本文包含如下部分: + +- HPM6E00EVK 板级资源介绍 +- 快速上手指南 +- 参考链接 + +通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。在进阶使用指南章节,将会介绍更多高级功能,帮助开发者利用 RT-Thread 驱动更多板载资源。 + +## 板级资源介绍 + +HPM6800EVK 是由先楫半导体推出的一款基于RISCV内核的开发板,带有丰富的片上资源和板上资源,可用于网络互联、音频和电机控制等应用。 + +开发板外观如下图所示: + +![board](figures/board.png) + + +## 板载外设 + +本 BSP 目前对外设的支持情况如下: + + +| **板载外设** | **支持情况** | **备注** | +| ------------------------ | ----------- | ------------------------------------- | +| USB | √ | | +| QSPI Flash | √ | | +| 以太网 | √ | | +| GPIO | √ | | +| SPI | √ | | +| I2C | √ | | +| RTC | √ | | +| PWM | √ | | +| 板载调试器 | √ | ft2232 | + + +## 使用说明 + +### 快速开始 + +本BSP支持通过`scons`命令来完成编译,在开始之前,需要先准备好开发所需的环境。 + +#### 准备环境 +- 步骤 1: 准备 [RT-Thread ENV](https://www.rt-thread.org/download.html#download-rt-thread-env-tool) +- 步骤 2: 准备 [toolcahin](https://github.com/helloeagleyang/riscv32-gnu-toolchain-win/archive/2022.04.12.zip) + - 下载并解压到指定的目录,如: `C:\DevTools\riscv32-gnu-toolchain` +- 步骤 3: 设置环境变量: `RTT_RISCV_TOOLCHAIN` 为 `\bin`, 如: `C:\DevTools\riscv32-gnu-toolchain\bin` +- 步骤 4: 准备 [OpenOCD](https://github.com/hpmicro/rtt-debugger-support-package/archive/v0.4.0.zip) + - 下载并解压到指定目录,如: `C:\DevTools\openocd-hpmicro` + - 将 `OPENOCD_HPMICRO`环境变量设置为 `\bin`,如: `C:\DevTools\openocd-hpmicro\bin` + +#### 配置和构建工程 + +通过 RT-Thread ENV 命令行切换目录到当前BSP所在目录后,用户可以: + +- 通过 `menuconfig` 命令 配置RT-Thread BSP的功能 +- 通过 `scons -jN` 命令完成构建, 其中`N` 最大值可以指定为CP拥有的物理内核数 +- 通过 `scons -c` 命令清除构建 + +#### 硬件连接 + +- 将BOOT 引脚拨到2'b00 +- 通过 TYPE-C线将板上的 `PWR_DEBUG` 连接到电脑 + +#### 下载 和 调试 + +- 通过如下命令完成下载: + ```console + %OPENOCD_HPMICRO%\openocd.exe -f boards\debug_scripts\probes\ft2232.cfg -f boards\debug_scripts\soc\hpm6e80-single-core.cfg -f boards\debug_scripts\boards\hpm6e00evk.cfg -c "init; halt; flash write_image erase rtthread.elf; reset; shutdown" + ``` + +- 通过如下命令实现调试: + + - 通过 `OpenOCD` 来连接开发板: +```console +%OPENOCD_HPMICRO%\openocd.exe -f boards\debug_scripts\probes\ft2232.cfg -f boards\debug_scripts\soc\hpm6e80-single-core.cfg -f boards\debug_scripts\boards\hpm6e00evk.cfg +``` + - 通过 `GDB` 实现调试: +```console +%RTT_EXEC_PATH%\riscv32-unknown-elf-gdb.exe rtthread.elf +``` + + - 在`GDB Shell`中使用如下命令来加载和运行: + +```console +load +c +``` + +### **运行结果** + +一旦成功下载,程序会自动运行并打印如下结果,板载LED灯会周期性闪烁。 + +配置好串口终端(串口配置为115200, 8-N-1),按复位键后,串口终端会打印如下日志: + +``` + \ | / +- RT - Thread Operating System + / | \ 5.0.1 build Aug 16 2023 18:18:18 + 2006 - 2023 Copyright by RT-Thread team +``` + +## **参考链接** + +- [RT-Thread 文档中心](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/README) +- [RT-Thread Env](https://github.com/RT-Thread/rtthread-manual-doc/blob/master/env/env.md) +- [HPM6800EVK RT-Thread BSP 包](https://github.com/hpmicro/rtt-bsp-hpm6e00evk) \ No newline at end of file diff --git a/bsp/hpmicro/hpm6e00evk/SConscript b/bsp/hpmicro/hpm6e00evk/SConscript new file mode 100644 index 0000000000..014c428d0a --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/SConscript @@ -0,0 +1,17 @@ +# for module compiling +import os +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +ASFLAGS = ' -I' + cwd + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/hpmicro/hpm6e00evk/SConstruct b/bsp/hpmicro/hpm6e00evk/SConstruct new file mode 100644 index 0000000000..d4047fc180 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/SConstruct @@ -0,0 +1,75 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../../../rt-thread') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +AddOption('--run', + dest = 'run', + type='string', + nargs=1, + action = 'store', + default = "", + help = 'Upload or debug application using openocd') + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS, + CXXCOM = '$CXX -o $TARGET -c $CXXFLAGS $_CCCOMCOM $SOURCES') + +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] + +Export('RTT_ROOT') +Export('rtconfig') + +SDK_ROOT = os.path.abspath('./') + +if os.path.exists(os.path.join(SDK_ROOT, 'libraries')): + libraries_path_prefix = os.path.join(SDK_ROOT, 'libraries') +else: + libraries_path_prefix = os.path.join(os.path.dirname(SDK_ROOT), 'libraries') + +SDK_LIB = libraries_path_prefix +Export('SDK_LIB') + + +GDB = rtconfig.GDB + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +hpm_library = 'hpm_sdk' +rtconfig.BSP_LIBRARY_TYPE = hpm_library + +# include soc +objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library,'soc', rtconfig.SOC_FAMILY, rtconfig.CHIP_NAME, 'SConscript'))) + +# include libraries +objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'SConscript'))) + +# include components +objs.extend(SConscript(os.path.join(libraries_path_prefix, hpm_library, 'components', 'SConscript'))) + + +# includes rtt drivers +objs.extend(SConscript(os.path.join(libraries_path_prefix, 'drivers', 'SConscript'))) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/hpmicro/hpm6e00evk/applications/SConscript b/bsp/hpmicro/hpm6e00evk/applications/SConscript new file mode 100644 index 0000000000..a65aa4d855 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/applications/SConscript @@ -0,0 +1,14 @@ +import rtconfig + +from building import * + +cwd = GetCurrentDir() + +src = Glob('*.c') + +CPPDEFINES=[] +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES) + +Return('group') diff --git a/bsp/hpmicro/hpm6e00evk/applications/main.c b/bsp/hpmicro/hpm6e00evk/applications/main.c new file mode 100644 index 0000000000..a5a7f07c73 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/applications/main.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021-2024 HPMicro + * + * Change Logs: + * Date Author Notes + * 2021-08-13 Fan YANG first version + * + */ + +#include +#include +#include "rtt_board.h" + +void thread_entry(void *arg); + +int main(void) +{ + app_init_led_pins(); + + static uint32_t led_thread_arg = 0; + rt_thread_t led_thread = rt_thread_create("led_th", thread_entry, &led_thread_arg, 1024, 1, 10); + rt_thread_startup(led_thread); + + return 0; +} + +void thread_entry(void *arg) +{ + while(1){ + app_led_write(0, APP_LED_ON); + rt_thread_mdelay(500); + app_led_write(0, APP_LED_OFF); + rt_thread_mdelay(500); + app_led_write(1, APP_LED_ON); + rt_thread_mdelay(500); + app_led_write(1, APP_LED_OFF); + rt_thread_mdelay(500); + app_led_write(2, APP_LED_ON); + rt_thread_mdelay(500); + app_led_write(2, APP_LED_OFF); + rt_thread_mdelay(500); + } +} diff --git a/bsp/hpmicro/hpm6e00evk/board/Kconfig b/bsp/hpmicro/hpm6e00evk/board/Kconfig new file mode 100644 index 0000000000..180c7d1a05 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/Kconfig @@ -0,0 +1,302 @@ +menu "Hardware Drivers Config" + +config SOC_HPM6E00 + bool + select SOC_SERIES_HPM6E00 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +config BSP_USING_ENET_PHY_RTL8211 + bool + default n + +menu "On-chip Peripheral Drivers" + config BSP_USING_GPIO + bool "Enable GPIO" + select RT_USING_PIN if BSP_USING_GPIO + default n + + menuconfig BSP_USING_UART + bool "Enable UART" + default y + select RT_USING_SERIAL + if BSP_USING_UART + menuconfig BSP_USING_UART0 + bool "Enable UART0 (Debugger)" + default y + if BSP_USING_UART0 + config BSP_UART0_RX_USING_DMA + bool "Enable UART0 RX DMA" + depends on BSP_USING_UART0 && RT_SERIAL_USING_DMA + default n + config BSP_UART0_TX_USING_DMA + bool "Enable UART0 TX DMA" + depends on BSP_USING_UART0 && RT_SERIAL_USING_DMA + default n + config BSP_UART0_RX_BUFSIZE + int "Set UART0 RX buffer size" + range 64 65535 + depends on RT_USING_SERIAL_V2 + default 128 + config BSP_UART0_TX_BUFSIZE + int "Set UART0 TX buffer size" + range 0 65535 + depends on RT_USING_SERIAL_V2 + default 0 + endif + menuconfig BSP_USING_UART1 + bool "Enable UART1" + default y + if BSP_USING_UART1 + config BSP_UART1_RX_USING_DMA + bool "Enable UART1 RX DMA" + depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA + default n + config BSP_UART1_TX_USING_DMA + bool "Enable UART1 TX DMA" + depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA + default n + config BSP_UART1_RX_BUFSIZE + int "Set UART1 RX buffer size" + range 64 65535 + depends on RT_USING_SERIAL_V2 + default 1024 + config BSP_UART1_TX_BUFSIZE + int "Set UART1 TX buffer size" + range 0 65535 + depends on RT_USING_SERIAL_V2 + default 0 + endif + endif + + + menuconfig BSP_USING_SPI + bool "Enable SPI" + default n + select RT_USING_SPI if BSP_USING_SPI + if BSP_USING_SPI + config BSP_USING_SPI7 + bool "Enable SPI7" + default n + if BSP_USING_SPI7 + config BSP_SPI7_USING_DMA + bool "Enable SPI7 DMA" + default n + choice + prompt "Select SPI7 CS TYPE" + default BSP_SPI7_USING_SOFT_CS + config BSP_SPI7_USING_SOFT_CS + bool "Enable SPI7 software cs" + config BSP_SPI7_USING_HARD_CS + bool "Enable SPI7 hardware cs" + endchoice + endif + endif + + menuconfig BSP_USING_RTC + bool "Enable RTC" + default n + + menuconfig BSP_USING_ETH + bool "Enable Ethernet" + default n + + select RT_USING_ETH + if BSP_USING_ETH + choice + prompt "ETH" + default BSP_USING_ETH0 + + config BSP_USING_ETH0 + bool "Enable ETH0" + select BSP_USING_ENET_PHY_RTL8211 + endchoice + endif + + menuconfig BSP_USING_GPTMR + bool "Enable GPTMR" + default n + select RT_USING_HWTIMER if BSP_USING_GPTMR + if BSP_USING_GPTMR + config BSP_USING_GPTMR0 + bool "Enable GPTMR0" + default n + config BSP_USING_GPTMR1 + bool "Enable GPTMR1" + default n + config BSP_USING_GPTMR2 + bool "Enable GPTMR2" + default n + config BSP_USING_GPTMR3 + bool "Enable GPTMR3" + default n + config BSP_USING_GPTMR4 + bool "Enable GPTMR4" + default n + config BSP_USING_GPTMR5 + bool "Enable GPTMR5" + default n + config BSP_USING_GPTMR6 + bool "Enable GPTMR6" + default n + config BSP_USING_GPTMR7 + bool "Enable GPTMR7" + default n + endif + + menuconfig BSP_USING_I2C + bool "Enable I2C" + default n + select RT_USING_I2C if BSP_USING_I2C + if BSP_USING_I2C + config BSP_USING_I2C0 + bool "Enable I2C0" + default y + config BSP_USING_I2C1 + bool "Enable I2C1" + default n + config BSP_USING_I2C3 + bool "Enable I2C3" + default n + endif + if BSP_USING_I2C0 + config BSP_I2C0_USING_DMA + bool "Enable I2C0 DMA" + default n + endif + if BSP_USING_I2C1 + config BSP_I2C1_USING_DMA + bool "Enable I2C1 DMA" + default n + endif + if BSP_USING_I2C3 + config BSP_I2C3_USING_DMA + bool "Enable I2C3 DMA" + default n + endif + + + menuconfig BSP_USING_XPI_FLASH + bool "Enable XPI FLASH" + default n + select RT_USING_FAL if BSP_USING_XPI_FLASH + + menuconfig BSP_USING_DAO + bool "Enable Audio DAO play" + default n + select RT_USING_AUDIO if BSP_USING_DAO + + menuconfig BSP_USING_PDM + bool "Enable Audio PDM record" + default n + select RT_USING_AUDIO if BSP_USING_PDM + + menuconfig BSP_USING_I2S + bool "Enable Audio I2S device" + default n + select RT_USING_AUDIO if BSP_USING_I2S + if BSP_USING_I2S + config BSP_USING_I2S3 + bool "Enable I2S3" + default y + config BSP_USING_AUDIO_CODEC_WM8960 + bool "Enable audio codec on board" + default y + endif + + menuconfig BSP_USING_USB + bool "Enable USB" + default n + if BSP_USING_USB + config BSP_USING_USB_DEVICE + bool "Enable USB Device" + default n + config BSP_USING_USB_HOST + bool "Enable USB Host" + select RT_USING_CACHE + default n + endif + + + menuconfig BSP_USING_EWDG + bool "Enable EWDG" + default n + select RT_USING_WDT if BSP_USING_EWDG + if BSP_USING_EWDG + config BSP_USING_EWDG0 + bool "Enable EWDG0" + default n + config BSP_USING_EWDG1 + bool "Enable EWDG1" + default n + endif + + menuconfig BSP_USING_PWMV2 + bool "Enable PWM" + default n + + menuconfig BSP_USING_MCAN + bool "Enable MCAN" + default n + select RT_USING_CAN if BSP_USING_MCAN + if BSP_USING_MCAN + config BSP_USING_MCAN0 + bool "Enable MCAN0" + default n + config BSP_USING_MCAN1 + bool "Enable MCAN1" + default n + config BSP_USING_MCAN2 + bool "Enable MCAN2" + default n + config BSP_USING_MCAN3 + bool "Enable MCAN3" + default n + config BSP_USING_MCAN4 + bool "Enable MCAN4" + default n + config BSP_USING_MCAN5 + bool "Enable MCAN5" + default n + config BSP_USING_MCAN6 + bool "Enable MCAN6" + default n + config BSP_USING_MCAN7 + bool "Enable MCAN7" + default n + endif + + menuconfig BSP_USING_ADC + bool "Enable ADC" + default n + select RT_USING_ADC if BSP_USING_ADC + if BSP_USING_ADC + menuconfig BSP_USING_ADC12 + bool "Enable ADC12" + default n + if BSP_USING_ADC12 + config BSP_USING_ADC0 + bool "Enable ADC0" + default n + config BSP_USING_ADC1 + bool "Enable ADC1" + default n + config BSP_USING_ADC2 + bool "Enable ADC2" + default n + endif + menuconfig BSP_USING_ADC16 + bool "Enable ADC16" + default n + if BSP_USING_ADC16 + config BSP_USING_ADC0 + bool "Enable ADC0" + default n + endif + endif + +endmenu + +endmenu + diff --git a/bsp/hpmicro/hpm6e00evk/board/SConscript b/bsp/hpmicro/hpm6e00evk/board/SConscript new file mode 100644 index 0000000000..d6bfd64ec2 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/SConscript @@ -0,0 +1,19 @@ +from building import * + +cwd = GetCurrentDir() + +# add the general drivers +src = Split(""" + board.c + rtt_board.c + pinmux.c + fal_flash_port.c + hpm_wm8960.c +""") + +CPPPATH = [cwd] +CPPDEFINES=['D45', 'HPM6880'] + +group = DefineGroup('Board', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/hpmicro/hpm6e00evk/board/board.c b/bsp/hpmicro/hpm6e00evk/board/board.c new file mode 100644 index 0000000000..fc95b92eea --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/board.c @@ -0,0 +1,1132 @@ +/* + * Copyright (c) 2023-2024 HPMicro + * SPDX-License-Identifier: BSD-3-Clause + * + * + */ + +#include "board.h" +#include "hpm_uart_drv.h" +#include "hpm_gptmr_drv.h" +#include "hpm_i2c_drv.h" +#include "hpm_gpio_drv.h" +#include "pinmux.h" +#include "hpm_pmp_drv.h" +#include "hpm_clock_drv.h" +#include "hpm_sysctl_drv.h" +#include "hpm_pllctlv2_drv.h" +#include "hpm_pcfg_drv.h" +#include "hpm_enet_drv.h" +#include "hpm_usb_drv.h" +#include "hpm_femc_drv.h" +#include "hpm_pwmv2_drv.h" +#include "hpm_esc_drv.h" + +static board_timer_cb timer_cb; + +/** + * @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"))) const uint32_t option[4] = { 0xfcf90001, 0x00000007, 0x0, 0x0 }; +#endif + +#if defined(FLASH_UF2) && FLASH_UF2 +ATTR_PLACE_AT(".uf2_signature") const uint32_t uf2_signature = BOARD_UF2_SIGNATURE; +#endif + +void board_init_console(void) +{ +#if !defined(CONFIG_NDEBUG_CONSOLE) || !CONFIG_NDEBUG_CONSOLE +#if BOARD_CONSOLE_TYPE == CONSOLE_TYPE_UART + console_config_t cfg; + + /* 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); + + /* Configure the UART clock to 24MHz */ + clock_set_source_divider(BOARD_CONSOLE_UART_CLK_NAME, clk_src_osc24m, 1U); + clock_add_to_group(BOARD_CONSOLE_UART_CLK_NAME, 0); + + cfg.type = BOARD_CONSOLE_TYPE; + cfg.base = (uint32_t) BOARD_CONSOLE_UART_BASE; + cfg.src_freq_in_hz = clock_get_frequency(BOARD_CONSOLE_UART_CLK_NAME); + cfg.baudrate = BOARD_CONSOLE_UART_BAUDRATE; + + if (status_success != console_init(&cfg)) { + /* failed to initialize debug console */ + while (1) { + } + } +#else + while (1) + ; +#endif +#endif +} + +void board_print_clock_freq(void) +{ + printf("==============================\n"); + printf(" %s clock summary\n", BOARD_NAME); + printf("==============================\n"); + printf("cpu0:\t\t %dHz\n", clock_get_frequency(clock_cpu0)); + printf("cpu1:\t\t %dHz\n", clock_get_frequency(clock_cpu1)); + printf("ahb:\t\t %luHz\n", clock_get_frequency(clock_ahb0)); + printf("axif:\t\t %dHz\n", clock_get_frequency(clock_axif)); + printf("axis:\t\t %dHz\n", clock_get_frequency(clock_axis)); + printf("axic:\t\t %dHz\n", clock_get_frequency(clock_axic)); + printf("axin:\t\t %dHz\n", clock_get_frequency(clock_axin)); + printf("xpi0:\t\t %dHz\n", clock_get_frequency(clock_xpi0)); + printf("femc:\t\t %luHz\n", clock_get_frequency(clock_femc)); + printf("mchtmr0:\t %dHz\n", clock_get_frequency(clock_mchtmr0)); + printf("mchtmr1:\t %dHz\n", clock_get_frequency(clock_mchtmr1)); + printf("==============================\n"); +} + +void board_init_uart(UART_Type *ptr) +{ + /* configure uart's pin before opening uart's clock */ + init_uart_pins(ptr); + board_init_uart_clock(ptr); +} + +void board_print_banner(void) +{ + const uint8_t banner[] = { "\n\ +----------------------------------------------------------------------\n\ +$$\\ $$\\ $$$$$$$\\ $$\\ $$\\ $$\\\n\ +$$ | $$ |$$ __$$\\ $$$\\ $$$ |\\__|\n\ +$$ | $$ |$$ | $$ |$$$$\\ $$$$ |$$\\ $$$$$$$\\ $$$$$$\\ $$$$$$\\\n\ +$$$$$$$$ |$$$$$$$ |$$\\$$\\$$ $$ |$$ |$$ _____|$$ __$$\\ $$ __$$\\\n\ +$$ __$$ |$$ ____/ $$ \\$$$ $$ |$$ |$$ / $$ | \\__|$$ / $$ |\n\ +$$ | $$ |$$ | $$ |\\$ /$$ |$$ |$$ | $$ | $$ | $$ |\n\ +$$ | $$ |$$ | $$ | \\_/ $$ |$$ |\\$$$$$$$\\ $$ | \\$$$$$$ |\n\ +\\__| \\__|\\__| \\__| \\__|\\__| \\_______|\\__| \\______/\n\ +----------------------------------------------------------------------\n" }; +#ifdef SDK_VERSION_STRING + printf("hpm_sdk: %s\n", SDK_VERSION_STRING); +#endif + printf("%s", banner); +} + +void board_ungate_mchtmr_at_lp_mode(void) +{ + /* Keep cpu clock on wfi, so that mchtmr irq can still work after wfi */ + sysctl_set_cpu_lp_mode(HPM_SYSCTL, BOARD_RUNNING_CORE, cpu_lp_mode_ungate_cpu_clock); +} + +static void board_turnoff_rgb_led(void) +{ + uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PE_SET(BOARD_LED_OFF_LEVEL); + HPM_IOC->PAD[IOC_PAD_PE14].FUNC_CTL = IOC_PE14_FUNC_CTL_GPIO_E_14; + HPM_IOC->PAD[IOC_PAD_PE15].FUNC_CTL = IOC_PE15_FUNC_CTL_GPIO_E_15; + HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_GPIO_E_04; + + HPM_IOC->PAD[IOC_PAD_PE14].PAD_CTL = pad_ctl; + HPM_IOC->PAD[IOC_PAD_PE15].PAD_CTL = pad_ctl; + HPM_IOC->PAD[IOC_PAD_PE04].PAD_CTL = pad_ctl; +} + +void board_init(void) +{ + board_turnoff_rgb_led(); + board_init_clock(); + board_init_console(); + board_init_pmp(); +#if BOARD_SHOW_CLOCK + board_print_clock_freq(); +#endif +#if BOARD_SHOW_BANNER + board_print_banner(); +#endif +} + +void board_init_core1(void) +{ + board_init_console(); + board_init_pmp(); +} + +void board_init_sdram_pins(void) +{ + init_femc_pins(); +} + +uint32_t board_init_femc_clock(void) +{ + clock_add_to_group(clock_femc, 0); + + /* Default FEMC clock is 166MHz */ + + /* Configure the FEMC to 133MHz */ + /* clock_set_source_divider(clock_femc, clk_src_pll1_clk0, 6U); */ + + return clock_get_frequency(clock_femc); +} + +void board_delay_us(uint32_t us) +{ + clock_cpu_delay_us(us); +} + +void board_delay_ms(uint32_t ms) +{ + clock_cpu_delay_ms(ms); +} + +void board_timer_isr(void) +{ + if (gptmr_check_status(BOARD_CALLBACK_TIMER, GPTMR_CH_RLD_STAT_MASK(BOARD_CALLBACK_TIMER_CH))) { + gptmr_clear_status(BOARD_CALLBACK_TIMER, GPTMR_CH_RLD_STAT_MASK(BOARD_CALLBACK_TIMER_CH)); + timer_cb(); + } +} + +SDK_DECLARE_EXT_ISR_M(BOARD_CALLBACK_TIMER_IRQ, board_timer_isr); + +void board_timer_create(uint32_t ms, board_timer_cb cb) +{ + uint32_t gptmr_freq; + gptmr_channel_config_t config; + + timer_cb = cb; + gptmr_channel_get_default_config(BOARD_CALLBACK_TIMER, &config); + + clock_add_to_group(BOARD_CALLBACK_TIMER_CLK_NAME, 0); + gptmr_freq = clock_get_frequency(BOARD_CALLBACK_TIMER_CLK_NAME); + + config.reload = gptmr_freq / 1000 * ms; + gptmr_channel_config(BOARD_CALLBACK_TIMER, BOARD_CALLBACK_TIMER_CH, &config, false); + gptmr_enable_irq(BOARD_CALLBACK_TIMER, GPTMR_CH_RLD_IRQ_MASK(BOARD_CALLBACK_TIMER_CH)); + intc_m_enable_irq_with_priority(BOARD_CALLBACK_TIMER_IRQ, 1); + + gptmr_start_counter(BOARD_CALLBACK_TIMER, BOARD_CALLBACK_TIMER_CH); +} + +void board_i2c_bus_clear(I2C_Type *ptr) +{ + if (i2c_get_line_scl_status(ptr) == false) { + printf("CLK is low, please power cycle the board\n"); + while (1) { + } + } + if (i2c_get_line_sda_status(ptr) == false) { + printf("SDA is low, try to issue I2C bus clear\n"); + } else { + printf("I2C bus is ready\n"); + return; + } + i2s_gen_reset_signal(ptr, 9); + board_delay_ms(100); + printf("I2C bus is cleared\n"); +} + +void board_init_i2c(I2C_Type *ptr) +{ + i2c_config_t config; + hpm_stat_t stat; + uint32_t freq; + if (ptr == NULL) { + return; + } + + init_i2c_pins(ptr); + board_i2c_bus_clear(ptr); + + if (ptr == HPM_I2C0) { + clock_add_to_group(clock_i2c0, 0); + } else if (ptr == HPM_I2C1) { + clock_add_to_group(clock_i2c1, 0); + } else if (ptr == HPM_I2C2) { + clock_add_to_group(clock_i2c2, 0); + } else if (ptr == HPM_I2C3) { + clock_add_to_group(clock_i2c3, 0); + } else if (ptr == HPM_I2C4) { + clock_add_to_group(clock_i2c4, 0); + } else if (ptr == HPM_I2C5) { + clock_add_to_group(clock_i2c5, 0); + } else if (ptr == HPM_I2C6) { + clock_add_to_group(clock_i2c6, 0); + } else if (ptr == HPM_I2C7) { + clock_add_to_group(clock_i2c7, 0); + } else { + ; + } + + /* Configure the I2C clock to 24MHz */ + /* clock_set_source_divider(BOARD_APP_I2C_CLK_NAME, clk_src_osc24m, 1U); */ + + config.i2c_mode = i2c_mode_normal; + config.is_10bit_addressing = false; + freq = clock_get_frequency(BOARD_APP_I2C_CLK_NAME); + stat = i2c_init_master(ptr, freq, &config); + if (stat != status_success) { + printf("failed to initialize i2c 0x%lx\n", (uint32_t) ptr); + while (1) { + } + } +} + +uint32_t board_init_spi_clock(SPI_Type *ptr) +{ + if (ptr == HPM_SPI1) { + /* SPI1 clock configure */ + clock_add_to_group(clock_spi1, 0); + /* clock_set_source_divider(clock_spi1, clk_src_pll0_clk0, 5U); */ + + return clock_get_frequency(clock_spi1); + } else if (ptr == HPM_SPI3) { + /* SPI3 clock configure */ + clock_add_to_group(clock_spi3, 0); + /* clock_set_source_divider(clock_spi3, clk_src_pll0_clk0, 5U); */ + + return clock_get_frequency(clock_spi3); + } else if (ptr == HPM_SPI6) { + /* SPI6 clock configure */ + clock_add_to_group(clock_spi6, 0); + /* clock_set_source_divider(clock_spi6, clk_src_pll0_clk0, 5U); */ + + return clock_get_frequency(clock_spi6); + } else if (ptr == HPM_SPI7) { + /* SPI6 clock configure */ + clock_add_to_group(clock_spi7, 0); + /* clock_set_source_divider(clock_spi6, clk_src_pll0_clk0, 5U); */ + + return clock_get_frequency(clock_spi7); + } + return 0; +} + +void board_init_gpio_pins(void) +{ + init_gpio_pins(); + /* Key A*/ + gpio_set_pin_input(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN); + /* Key B*/ + gpio_set_pin_input(BOARD_APP_GPIO_CTRL2, BOARD_APP_GPIO_INDEX2, BOARD_APP_GPIO_PIN2); +} + +void board_init_spi_pins(SPI_Type *ptr) +{ + init_spi_pins(ptr); +} + +void board_init_spi_pins_with_gpio_as_cs(SPI_Type *ptr) +{ + init_spi_pins_with_gpio_as_cs(ptr); + gpio_set_pin_output_with_initial(BOARD_SPI_CS_GPIO_CTRL, GPIO_GET_PORT_INDEX(BOARD_SPI_CS_PIN), + GPIO_GET_PIN_INDEX(BOARD_SPI_CS_PIN), !BOARD_SPI_CS_ACTIVE_LEVEL); +} + +void board_write_spi_cs(uint32_t pin, uint8_t state) +{ + gpio_write_pin(BOARD_SPI_CS_GPIO_CTRL, GPIO_GET_PORT_INDEX(pin), GPIO_GET_PIN_INDEX(pin), state); +} + +uint8_t board_get_led_pwm_off_level(void) +{ + return BOARD_LED_OFF_LEVEL; +} + +uint8_t board_get_led_gpio_off_level(void) +{ + return BOARD_LED_OFF_LEVEL; +} + +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_get_led_gpio_off_level()); + gpio_set_pin_output_with_initial(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, board_get_led_gpio_off_level()); + gpio_set_pin_output_with_initial(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, board_get_led_gpio_off_level()); +} + +void board_led_toggle(void) +{ +#ifdef BOARD_LED_TOGGLE_RGB + static uint8_t i; + switch (i) { + case 1: + gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, BOARD_LED_OFF_LEVEL); + gpio_write_pin(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, BOARD_LED_ON_LEVEL); + gpio_write_pin(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, BOARD_LED_OFF_LEVEL); + break; + + case 2: + gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, BOARD_LED_OFF_LEVEL); + gpio_write_pin(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, BOARD_LED_OFF_LEVEL); + gpio_write_pin(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, BOARD_LED_ON_LEVEL); + break; + + case 0: + default: + gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, BOARD_LED_ON_LEVEL); + gpio_write_pin(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, BOARD_LED_OFF_LEVEL); + gpio_write_pin(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, BOARD_LED_OFF_LEVEL); + break; + } + i++; + i = i % 3; +#else + gpio_toggle_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN); +#endif +} + +void board_led_write(uint8_t state) +{ + gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, state); +} + +static void set_rgb_output_off(PWMV2_Type *ptr, uint8_t counter, uint8_t channel, uint8_t shadow_id, uint8_t cmp_id) +{ + +} + +void board_init_rgb_pwm_pins(void) +{ + board_turnoff_rgb_led(); + + set_rgb_output_off(BOARD_RED_PWM, BOARD_RED_PWM_COUNTER_INDEX, BOARD_RED_PWM_OUT_CH, BOARD_RED_PWM_SHADOW_ID, BOARD_RED_PWM_CMP_ID); + set_rgb_output_off(BOARD_GREEN_PWM, BOARD_GREEN_PWM_COUNTER_INDEX, BOARD_GREEN_PWM_OUT_CH, BOARD_GREEN_PWM_SHADOW_ID, BOARD_GREEN_PWM_CMP_ID); + set_rgb_output_off(BOARD_BLUE_PWM, BOARD_BLUE_PWM_COUNTER_INDEX, BOARD_BLUE_PWM_OUT_CH, BOARD_BLUE_PWM_SHADOW_ID, BOARD_BLUE_PWM_CMP_ID); + + init_led_pins_as_pwm(); + +} + +void board_disable_output_rgb_led(uint8_t color) +{ + switch (color) { + case BOARD_RGB_RED: + pwmv2_channel_disable_output(BOARD_RED_PWM, BOARD_RED_PWM_OUT_CH); + break; + case BOARD_RGB_GREEN: + pwmv2_channel_disable_output(BOARD_GREEN_PWM, BOARD_GREEN_PWM_OUT_CH); + break; + case BOARD_RGB_BLUE: + pwmv2_channel_disable_output(BOARD_BLUE_PWM, BOARD_BLUE_PWM_OUT_CH); + break; + default: + while (1) { + ; + } + } +} + +void board_enable_output_rgb_led(uint8_t color) +{ + switch (color) { + case BOARD_RGB_RED: + pwmv2_channel_enable_output(BOARD_RED_PWM, BOARD_RED_PWM_OUT_CH); + break; + case BOARD_RGB_GREEN: + pwmv2_channel_enable_output(BOARD_GREEN_PWM, BOARD_GREEN_PWM_OUT_CH); + break; + case BOARD_RGB_BLUE: + pwmv2_channel_enable_output(BOARD_BLUE_PWM, BOARD_BLUE_PWM_OUT_CH); + break; + default: + while (1) { + ; + } + } +} + +void board_init_pmp(void) +{ + uint32_t start_addr; + uint32_t end_addr; + uint32_t length; + pmp_entry_t pmp_entry[16]; + 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++; + } + pmp_config(&pmp_entry[0], index); +} + +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 */ + pllctlv2_xtal_set_rampup_time(HPM_PLLCTLV2, 32ul * 1000ul * 9u); + + /* select clock setting preset1 */ + sysctl_clock_set_preset(HPM_SYSCTL, 2); + } + /* Add most Clocks to group 0 */ + /* not open uart clock in this API, uart should configure pin function before opening clock */ + clock_add_to_group(clock_cpu0, 0); + clock_add_to_group(clock_mchtmr0, 0); + clock_add_to_group(clock_ahb0, 0); + clock_add_to_group(clock_axif, 0); + clock_add_to_group(clock_axis, 0); + clock_add_to_group(clock_axic, 0); + clock_add_to_group(clock_axin, 0); + clock_add_to_group(clock_rom0, 0); + clock_add_to_group(clock_xpi0, 0); + clock_add_to_group(clock_lmm0, 0); + clock_add_to_group(clock_lmm1, 0); + clock_add_to_group(clock_ram0, 0); + clock_add_to_group(clock_ram1, 0); + clock_add_to_group(clock_hdma, 0); + clock_add_to_group(clock_xdma, 0); + clock_add_to_group(clock_femc, 0); + + clock_add_to_group(clock_gptmr0, 0); + clock_add_to_group(clock_gptmr1, 0); + clock_add_to_group(clock_gptmr2, 0); + clock_add_to_group(clock_gptmr3, 0); + clock_add_to_group(clock_gptmr4, 0); + clock_add_to_group(clock_gptmr5, 0); + clock_add_to_group(clock_gptmr6, 0); + clock_add_to_group(clock_gptmr7, 0); + clock_add_to_group(clock_ptpc, 0); + + clock_add_to_group(clock_puart, 0); + clock_add_to_group(clock_watchdog0, 0); + clock_add_to_group(clock_watchdog1, 0); + clock_add_to_group(clock_watchdog2, 0); + clock_add_to_group(clock_watchdog3, 0); + clock_add_to_group(clock_pwdg, 0); + + clock_add_to_group(clock_qei0, 0); + clock_add_to_group(clock_qei1, 0); + clock_add_to_group(clock_qei2, 0); + clock_add_to_group(clock_qei3, 0); + clock_add_to_group(clock_qeo0, 0); + clock_add_to_group(clock_qeo1, 0); + clock_add_to_group(clock_qeo2, 0); + clock_add_to_group(clock_qeo3, 0); + clock_add_to_group(clock_pwm0, 0); + clock_add_to_group(clock_pwm1, 0); + clock_add_to_group(clock_pwm2, 0); + clock_add_to_group(clock_pwm3, 0); + clock_add_to_group(clock_rdc0, 0); + clock_add_to_group(clock_rdc1, 0); + clock_add_to_group(clock_sdm0, 0); + clock_add_to_group(clock_sdm1, 0); + clock_add_to_group(clock_plb0, 0); + clock_add_to_group(clock_sei0, 0); + clock_add_to_group(clock_mtg0, 0); + clock_add_to_group(clock_mtg1, 0); + clock_add_to_group(clock_vsc0, 0); + clock_add_to_group(clock_vsc1, 0); + clock_add_to_group(clock_clc0, 0); + clock_add_to_group(clock_clc1, 0); + clock_add_to_group(clock_emds, 0); + + clock_add_to_group(clock_cmp0, 0); + clock_add_to_group(clock_cmp1, 0); + clock_add_to_group(clock_cmp2, 0); + clock_add_to_group(clock_cmp3, 0); + + clock_add_to_group(clock_crc0, 0); + clock_add_to_group(clock_tsns, 0); + clock_add_to_group(clock_mbx0, 0); + clock_add_to_group(clock_mbx1, 0); + clock_add_to_group(clock_gpio, 0); + clock_add_to_group(clock_ppi0, 0); + clock_add_to_group(clock_lobs, 0); + clock_add_to_group(clock_rng, 0); + clock_add_to_group(clock_sdp, 0); + clock_add_to_group(clock_pka, 0); + clock_add_to_group(clock_kman, 0); + clock_add_to_group(clock_ffa0, 0); + + clock_add_to_group(clock_usb0, 0); + clock_add_to_group(clock_esc0, 0); + clock_add_to_group(clock_eth0, 0); + clock_add_to_group(clock_ptp0, 0); + clock_add_to_group(clock_ntmr0, 0); + clock_add_to_group(clock_ref0, 0); + clock_add_to_group(clock_ref1, 0); + clock_add_to_group(clock_tsn1, 0); + clock_add_to_group(clock_tsn2, 0); + clock_add_to_group(clock_tsn3, 0); + + clock_add_to_group(clock_i2c0, 0); + clock_add_to_group(clock_i2c1, 0); + clock_add_to_group(clock_i2c2, 0); + clock_add_to_group(clock_i2c3, 0); + + clock_add_to_group(clock_adc0, 0); + clock_add_to_group(clock_adc1, 0); + clock_add_to_group(clock_adc2, 0); + clock_add_to_group(clock_adc3, 0); + + /* Connect Group0 to CPU0 */ + clock_connect_group_to_cpu(0, 0); + + /* Add the CPU1 clock to Group1 */ + clock_add_to_group(clock_cpu1, 0); + clock_add_to_group(clock_mchtmr1, 1); + + /* Connect Group1 to CPU1 */ + clock_connect_group_to_cpu(1, 1); + + /* Bump up DCDC voltage to 1200mv */ + pcfg_dcdc_set_voltage(HPM_PCFG, 1200); + + /* Configure mchtmr to 24MHz */ + clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1); + clock_set_source_divider(clock_mchtmr1, clk_src_osc24m, 1); + + clock_update_core_clock(); +} + +uint32_t board_init_uart_clock(UART_Type *ptr) +{ + uint32_t freq = 0U; + if (ptr == HPM_UART0) { + clock_set_source_divider(clock_uart0, clk_src_pll1_clk0, 10); + clock_add_to_group(clock_uart0, 0); + freq = clock_get_frequency(clock_uart0); + } else if (ptr == HPM_UART1) { + clock_set_source_divider(clock_uart1, clk_src_pll1_clk0, 10); + clock_add_to_group(clock_uart1, 0); + freq = clock_get_frequency(clock_uart1); + } else if (ptr == HPM_UART2) { + clock_set_source_divider(clock_uart2, clk_src_pll1_clk0, 10); + clock_add_to_group(clock_uart2, 0); + freq = clock_get_frequency(clock_uart2); + } else if (ptr == HPM_UART6) { + clock_set_source_divider(clock_uart6, clk_src_pll1_clk0, 10); + clock_add_to_group(clock_uart6, 0); + freq = clock_get_frequency(clock_uart6); + } else { + /* Not supported */ + } + return freq; +} + +#ifdef INIT_EXT_RAM_FOR_DATA +/* + * this function will be called during startup to initialize external memory for data use + */ +void _init_ext_ram(void) +{ + uint32_t femc_clk_in_hz; + board_init_sdram_pins(); + femc_clk_in_hz = board_init_femc_clock(); + + femc_config_t config = {0}; + femc_sdram_config_t sdram_config = {0}; + + femc_default_config(HPM_FEMC, &config); + femc_init(HPM_FEMC, &config); + + femc_get_typical_sdram_config(HPM_FEMC, &sdram_config); + + sdram_config.bank_num = FEMC_SDRAM_BANK_NUM_4; + sdram_config.prescaler = 0x3; + sdram_config.burst_len_in_byte = 8; + sdram_config.auto_refresh_count_in_one_burst = 1; + sdram_config.col_addr_bits = FEMC_SDRAM_COLUMN_ADDR_9_BITS; + sdram_config.cas_latency = FEMC_SDRAM_CAS_LATENCY_3; + + sdram_config.refresh_to_refresh_in_ns = 60; /* Trc */ + sdram_config.refresh_recover_in_ns = 60; /* Trc */ + sdram_config.act_to_precharge_in_ns = 42; /* Tras */ + sdram_config.act_to_rw_in_ns = 18; /* Trcd */ + sdram_config.precharge_to_act_in_ns = 18; /* Trp */ + sdram_config.act_to_act_in_ns = 12; /* Trrd */ + sdram_config.write_recover_in_ns = 12; /* Twr/Tdpl */ + sdram_config.self_refresh_recover_in_ns = 72; /* Txsr */ + + sdram_config.cs = BOARD_SDRAM_CS; + sdram_config.base_address = BOARD_SDRAM_ADDRESS; + sdram_config.size_in_byte = BOARD_SDRAM_SIZE; + sdram_config.port_size = BOARD_SDRAM_PORT_SIZE; + sdram_config.refresh_count = BOARD_SDRAM_REFRESH_COUNT; + sdram_config.refresh_in_ms = BOARD_SDRAM_REFRESH_IN_MS; + sdram_config.delay_cell_disable = true; + sdram_config.delay_cell_value = 0; + + femc_config_sdram(HPM_FEMC, femc_clk_in_hz, &sdram_config); + + HPM_FEMC->SDRCTRL0 |= FEMC_SDRCTRL0_HIGHBAND_MASK; /* use data[31:16] for 16bit SDRAM */ +} +#endif + +void board_init_usb_pins(void) +{ + init_usb_pins(); + usb_hcd_set_power_ctrl_polarity(BOARD_USB, true); + /* Wait USB_PWR pin control vbus power stable. Time depend on decoupling capacitor, you can decrease or increase this time */ + board_delay_ms(100); +} + +void board_usb_vbus_ctrl(uint8_t usb_index, uint8_t level) +{ + (void) usb_index; + (void) level; +} + +uint32_t board_init_dao_clock(void) +{ + clock_add_to_group(clock_dao, 0); + + board_config_i2s_clock(DAO_I2S, 48000); + + return clock_get_frequency(clock_dao); +} + +uint32_t board_init_pdm_clock(void) +{ + clock_add_to_group(clock_pdm, 0); + + board_config_i2s_clock(PDM_I2S, 16000); + + return clock_get_frequency(clock_pdm); +} + +void board_init_i2s_pins(I2S_Type *ptr) +{ + init_i2s_pins(ptr); +} + +uint32_t board_config_i2s_clock(I2S_Type *ptr, uint32_t sample_rate) +{ + uint32_t freq = 0; + + if (ptr == HPM_I2S0) { + clock_add_to_group(clock_i2s0, 0); + if ((sample_rate % 22050) == 0) { + clock_set_source_divider(clock_aud0, clk_src_pll1_clk0, 71); /* config clock_aud1 for 22050*n sample rate */ + } else { + clock_set_source_divider(clock_aud0, clk_src_pll2_clk0, 21); /* default 24576000Hz */ + } + clock_set_i2s_source(clock_i2s0, clk_i2s_src_aud0); + freq = clock_get_frequency(clock_i2s0); + } else if (ptr == HPM_I2S1) { + clock_add_to_group(clock_i2s1, 0); + if ((sample_rate % 22050) == 0) { + clock_set_source_divider(clock_aud1, clk_src_pll1_clk0, 71); /* config clock_aud1 for 22050*n sample rate */ + } else { + clock_set_source_divider(clock_aud1, clk_src_pll2_clk0, 21); /* default 24576000Hz */ + } + clock_set_i2s_source(clock_i2s1, clk_i2s_src_aud1); + freq = clock_get_frequency(clock_i2s1); + } else { + ; + } + + return freq; +} + +void board_init_adc16_pins(void) +{ + init_adc16_pins(); +} + +uint32_t board_init_adc16_clock(void *ptr, bool clk_src_ahb) /* motor system should be use clk_adc_src_ahb0 */ +{ + uint32_t freq = 0; + + if (ptr == (void *)HPM_ADC0) { + if (clk_src_ahb) { + /* Configure the ADC clock from AHB (@200MHz by default)*/ + clock_set_adc_source(clock_adc0, clk_adc_src_ahb0); + } else { + /* Configure the ADC clock from ANA (@200MHz by default)*/ + clock_set_adc_source(clock_adc0, clk_adc_src_ana0); + clock_set_source_divider(clock_ana0, clk_src_pll1_clk0, 4U); + } + freq = clock_get_frequency(clock_adc0); + } else if (ptr == (void *)HPM_ADC1) { + if (clk_src_ahb) { + /* Configure the ADC clock from AHB (@200MHz by default)*/ + clock_set_adc_source(clock_adc1, clk_adc_src_ahb0); + } else { + /* Configure the ADC clock from ANA (@200MHz by default)*/ + clock_set_adc_source(clock_adc1, clk_adc_src_ana1); + clock_set_source_divider(clock_ana0, clk_src_pll1_clk0, 4U); + } + freq = clock_get_frequency(clock_adc1); + } else if (ptr == (void *)HPM_ADC2) { + if (clk_src_ahb) { + /* Configure the ADC clock from AHB (@200MHz by default)*/ + clock_set_adc_source(clock_adc2, clk_adc_src_ahb0); + } else { + /* Configure the ADC clock from ANA (@200MHz by default)*/ + clock_set_adc_source(clock_adc2, clk_adc_src_ana2); + clock_set_source_divider(clock_ana0, clk_src_pll1_clk0, 4U); + } + freq = clock_get_frequency(clock_adc2); + } else if (ptr == (void *)HPM_ADC3) { + if (clk_src_ahb) { + /* Configure the ADC clock from AHB (@200MHz by default)*/ + clock_set_adc_source(clock_adc3, clk_adc_src_ahb0); + } else { + /* Configure the ADC clock from ANA (@200MHz by default)*/ + clock_set_adc_source(clock_adc3, clk_adc_src_ana3); + clock_set_source_divider(clock_ana0, clk_src_pll1_clk0, 4U); + } + freq = clock_get_frequency(clock_adc3); + } + + return freq; +} + +void board_init_can(MCAN_Type *ptr) +{ + init_can_pins(ptr); +} + +uint32_t board_init_can_clock(MCAN_Type *ptr) +{ + uint32_t freq = 0; + if (ptr == HPM_MCAN0) { + /* Set the CAN0 peripheral clock to 80MHz */ + clock_add_to_group(clock_can0, 0); + clock_set_source_divider(clock_can0, clk_src_pll1_clk0, 10); + freq = clock_get_frequency(clock_can0); + } else if (ptr == HPM_MCAN1) { + /* Set the CAN1 peripheral clock to 80MHz */ + clock_add_to_group(clock_can1, 0); + clock_set_source_divider(clock_can1, clk_src_pll1_clk0, 10); + freq = clock_get_frequency(clock_can1); + } else if (ptr == HPM_MCAN2) { + /* Set the CAN2 peripheral clock to 80MHz */ + clock_add_to_group(clock_can2, 0); + clock_set_source_divider(clock_can2, clk_src_pll1_clk0, 10); + freq = clock_get_frequency(clock_can2); + } else if (ptr == HPM_MCAN3) { + /* Set the CAN3 peripheral clock to 80MHz */ + clock_add_to_group(clock_can3, 0); + clock_set_source_divider(clock_can3, clk_src_pll1_clk0, 10); + freq = clock_get_frequency(clock_can3); + } else if (ptr == HPM_MCAN4) { + /* Set the CAN4 peripheral clock to 80MHz */ + clock_add_to_group(clock_can4, 0); + clock_set_source_divider(clock_can4, clk_src_pll1_clk0, 10); + freq = clock_get_frequency(clock_can4); + } else if (ptr == HPM_MCAN5) { + /* Set the CAN5 peripheral clock to 80MHz */ + clock_add_to_group(clock_can5, 0); + clock_set_source_divider(clock_can5, clk_src_pll1_clk0, 10); + freq = clock_get_frequency(clock_can5); + } else if (ptr == HPM_MCAN6) { + /* Set the CAN6 peripheral clock to 80MHz */ + clock_add_to_group(clock_can6, 0); + clock_set_source_divider(clock_can6, clk_src_pll1_clk0, 10); + freq = clock_get_frequency(clock_can6); + } else if (ptr == HPM_MCAN7) { + /* Set the CAN7 peripheral clock to 80MHz */ + clock_add_to_group(clock_can7, 0); + clock_set_source_divider(clock_can7, clk_src_pll1_clk0, 10); + freq = clock_get_frequency(clock_can3); + } else { + /* Invalid CAN instance */ + } + return freq; +} + +hpm_stat_t board_init_enet_ptp_clock(ENET_Type *ptr) +{ + /* set clock source */ + if (ptr == HPM_ENET0) { + /* make sure pll0_clk0 output clock at 400MHz to get a clock at 100MHz for the enet0 ptp function */ + /* clock_set_source_divider(clock_ptp0, clk_src_pll1_clk1, 4); */ /* 100MHz */ + } else if (ptr == HPM_ENET1) { + /* make sure pll0_clk0 output clock at 400MHz to get a clock at 100MHz for the enet1 ptp function */ + /* clock_set_source_divider(clock_ptp1, clk_src_pll1_clk1, 4); */ /* 100MHz */ + } else { + return status_invalid_argument; + } + + return status_success; +} + +hpm_stat_t board_init_enet_pins(ENET_Type *ptr) +{ + init_enet_pins(ptr); + + if (ptr == HPM_ENET0) { + gpio_set_pin_output_with_initial(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX, BOARD_ENET_RGMII_RST_GPIO_PIN, 0); + } else { + return status_invalid_argument; + } + + return status_success; +} + +hpm_stat_t board_reset_enet_phy(ENET_Type *ptr) +{ + if (ptr == HPM_ENET0) { + gpio_write_pin(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX, BOARD_ENET_RGMII_RST_GPIO_PIN, 0); + board_delay_ms(1); + gpio_write_pin(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX, BOARD_ENET_RGMII_RST_GPIO_PIN, 1); + } else { + return status_invalid_argument; + } + + return status_success; +} + +uint8_t board_get_enet_dma_pbl(ENET_Type *ptr) +{ + (void) ptr; + return enet_pbl_32; +} + +hpm_stat_t board_enable_enet_irq(ENET_Type *ptr) +{ + if (ptr == HPM_ENET0) { + intc_m_enable_irq(IRQn_ENET0); + } else { + return status_invalid_argument; + } + + return status_success; +} + +hpm_stat_t board_disable_enet_irq(ENET_Type *ptr) +{ + if (ptr == HPM_ENET0) { + intc_m_disable_irq(IRQn_ENET0); + } else { + return status_invalid_argument; + } + + return status_success; +} + +void board_init_enet_pps_pins(ENET_Type *ptr) +{ + (void) ptr; + init_enet_pps_pins(); +} + +hpm_stat_t board_init_enet_rmii_reference_clock(ENET_Type *ptr, bool internal) +{ + /* Configure Enet clock to output reference clock */ + if (ptr == HPM_ENET0) { + if (internal) { + /* set pll output frequency at 1GHz */ + if (pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, PLLCTLV2_PLL_PLL2, 1000000000UL) == status_success) { + /* set pll2_clk1 output frequence at 250MHz from PLL2 divided by 4 (1 + 15 / 5) */ + pllctlv2_set_postdiv(HPM_PLLCTLV2, PLLCTLV2_PLL_PLL2, 1, 15); + /* set eth clock frequency at 50MHz for enet0 */ + /* clock_set_source_divider(clock_eth0, clk_src_pll2_clk1, 5); */ + } else { + return status_fail; + } + } + } else { + return status_invalid_argument; + } + + enet_rmii_enable_clock(ptr, internal); /* defined in hpm_enet_soc_drv.h, not sure */ + + return status_success; +} + +hpm_stat_t board_init_enet_rgmii_clock_delay(ENET_Type *ptr) +{ + if (ptr == HPM_ENET0) { + return enet_rgmii_set_clock_delay(ptr, BOARD_ENET_RGMII_TX_DLY, BOARD_ENET_RGMII_RX_DLY); /* defined in hpm_enet_soc_drv.h, not sure */ + } + + return status_invalid_argument; +} + +void board_init_dao_pins(void) +{ + init_dao_pins(); +} + +void board_init_ethercat(ESC_Type *ptr) +{ + (void)ptr; + init_esc_pins(); + /* keep ECAT PHY reset */ + gpio_set_pin_output_with_initial(BOARD_ECAT_PHY0_RESET_GPIO, BOARD_ECAT_PHY0_RESET_GPIO_PORT_INDEX, BOARD_ECAT_PHY0_RESET_PIN_INDEX, BOARD_ECAT_PHY_RESET_LEVEL); + gpio_set_pin_output_with_initial(BOARD_ECAT_PHY1_RESET_GPIO, BOARD_ECAT_PHY1_RESET_GPIO_PORT_INDEX, BOARD_ECAT_PHY1_RESET_PIN_INDEX, BOARD_ECAT_PHY_RESET_LEVEL); +} + +/* input and output pin for ethercat io test */ +void board_init_switch_led(void) +{ + init_esc_in_out_pin(); + + gpio_set_pin_input(BOARD_ECAT_IN1_GPIO, BOARD_ECAT_IN1_GPIO_PORT_INDEX, BOARD_ECAT_IN1_GPIO_PIN_INDEX); + gpio_set_pin_input(BOARD_ECAT_IN2_GPIO, BOARD_ECAT_IN2_GPIO_PORT_INDEX, BOARD_ECAT_IN2_GPIO_PIN_INDEX); + + gpio_set_pin_output_with_initial(BOARD_ECAT_OUT1_GPIO, BOARD_ECAT_OUT1_GPIO_PORT_INDEX, BOARD_ECAT_OUT1_GPIO_PIN_INDEX, 0); + gpio_set_pin_output_with_initial(BOARD_ECAT_OUT2_GPIO, BOARD_ECAT_OUT2_GPIO_PORT_INDEX, BOARD_ECAT_OUT2_GPIO_PIN_INDEX, 0); +} + +void board_init_tsw(TSW_Type *ptr) +{ + (void)ptr; + + init_tsw_pins(); + + /* PORT1/PORT2: JL1111 RST(PA10) */ + gpio_set_pin_output_with_initial(HPM_GPIO0, GPIO_DO_GPIOA, 10, 0); + gpio_write_pin(HPM_GPIO0, GPIO_DO_GPIOA, 10, 0); + board_delay_ms(100); + gpio_write_pin(HPM_GPIO0, GPIO_DO_GPIOA, 10, 1); + + /* PORT3: RTL8211 RST(PA10) */ + gpio_set_pin_output_with_initial(HPM_GPIO0, GPIO_DO_GPIOA, 14, 0); + gpio_write_pin(HPM_GPIO0, GPIO_DO_GPIOA, 14, 0); + board_delay_ms(100); + gpio_write_pin(HPM_GPIO0, GPIO_DO_GPIOA, 14, 1); + + /* Enable XI clock for JL1111 */ + esc_core_enable_clock(HPM_ESC, true); + esc_phy_enable_clock(HPM_ESC, true); +} + +void board_init_sei_pins(SEI_Type *ptr, uint8_t sei_ctrl_idx) +{ + init_sei_pins(ptr, sei_ctrl_idx); +} + +void board_init_adc_qeiv2_pins(void) +{ + init_adc_qeiv2_pins(); +} + +uint32_t board_init_gptmr_clock(GPTMR_Type *ptr) +{ + uint32_t freq = 0; + + if (ptr == HPM_GPTMR0) { + clock_add_to_group(clock_gptmr0, 0); + clock_set_source_divider(clock_gptmr0, clk_src_pll1_clk0, 8); + freq = clock_get_frequency(clock_gptmr0); + } + else if (ptr == HPM_GPTMR1) { + clock_add_to_group(clock_gptmr1, 0); + clock_set_source_divider(clock_gptmr1, clk_src_pll1_clk0, 8); + freq = clock_get_frequency(clock_gptmr1); + } + else if (ptr == HPM_GPTMR2) { + clock_add_to_group(clock_gptmr2, 0); + clock_set_source_divider(clock_gptmr2, clk_src_pll1_clk0, 8); + freq = clock_get_frequency(clock_gptmr2); + } + else if (ptr == HPM_GPTMR3) { + clock_add_to_group(clock_gptmr3, 0); + clock_set_source_divider(clock_gptmr3, clk_src_pll1_clk0, 8); + freq = clock_get_frequency(clock_gptmr3); + } + else if (ptr == HPM_GPTMR4) { + clock_add_to_group(clock_gptmr4, 0); + clock_set_source_divider(clock_gptmr4, clk_src_pll1_clk0, 8); + freq = clock_get_frequency(clock_gptmr4); + } + else if (ptr == HPM_GPTMR5) { + clock_add_to_group(clock_gptmr5, 0); + clock_set_source_divider(clock_gptmr5, clk_src_pll1_clk0, 8); + freq = clock_get_frequency(clock_gptmr5); + } + else if (ptr == HPM_GPTMR6) { + clock_add_to_group(clock_gptmr6, 0); + clock_set_source_divider(clock_gptmr6, clk_src_pll1_clk0, 8); + freq = clock_get_frequency(clock_gptmr6); + } + else if (ptr == HPM_GPTMR7) { + clock_add_to_group(clock_gptmr7, 0); + clock_set_source_divider(clock_gptmr7, clk_src_pll1_clk0, 8); + freq = clock_get_frequency(clock_gptmr7); + } + else { + /* Invalid instance */ + } +} + +uint32_t board_init_pwm_clock(PWMV2_Type *ptr) +{ + uint32_t freq = 0; + if (ptr == HPM_PWM0) { + clock_add_to_group(clock_pwm0, 0); + freq = clock_get_frequency(clock_pwm0); + } else if (ptr == HPM_PWM1) { + clock_add_to_group(clock_pwm1, 0); + freq = clock_get_frequency(clock_pwm1); + } else if (ptr == HPM_PWM2) { + clock_add_to_group(clock_pwm2, 0); + freq = clock_get_frequency(clock_pwm2); + } else if (ptr == HPM_PWM3) { + clock_add_to_group(clock_pwm3, 0); + freq = clock_get_frequency(clock_pwm3); + } else { + + } + return freq; +} diff --git a/bsp/hpmicro/hpm6e00evk/board/board.h b/bsp/hpmicro/hpm6e00evk/board/board.h new file mode 100644 index 0000000000..75e9f2e12a --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/board.h @@ -0,0 +1,714 @@ +/* + * Copyright (c) 2024 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef _HPM_BOARD_H +#define _HPM_BOARD_H +#include +#include "hpm_common.h" +#include "hpm_clock_drv.h" +#include "hpm_soc.h" +#include "hpm_soc_feature.h" +#include "pinmux.h" +#if !defined(CONFIG_NDEBUG_CONSOLE) || !CONFIG_NDEBUG_CONSOLE +#include "hpm_debug_console.h" +#endif + +#define BOARD_NAME "hpm6e00evk" +#define BOARD_UF2_SIGNATURE (0x0A4D5048UL) +#define BOARD_CPU_FREQ (600000000UL) + +#define SEC_CORE_IMG_START CORE1_ILM_LOCAL_BASE + +#ifndef BOARD_RUNNING_CORE +#define BOARD_RUNNING_CORE HPM_CORE0 +#endif + +/* ACMP desction */ +#define BOARD_ACMP HPM_ACMP0 +#define BOARD_ACMP_CHANNEL ACMP_CHANNEL_CHN1 +#define BOARD_ACMP_IRQ IRQn_ACMP0_1 +#define BOARD_ACMP_PLUS_INPUT ACMP_INPUT_DAC_OUT /* use internal DAC */ +#define BOARD_ACMP_MINUS_INPUT ACMP_INPUT_ANALOG_4 /* align with used pin */ + +/* uart section */ +#ifndef BOARD_APP_UART_BASE +#define BOARD_APP_UART_BASE HPM_UART1 +#define BOARD_APP_UART_IRQ IRQn_UART1 +#define BOARD_APP_UART_BAUDRATE (115200UL) +#define BOARD_APP_UART_CLK_NAME clock_uart1 +#define BOARD_APP_UART_RX_DMA_REQ HPM_DMA_SRC_UART1_RX +#define BOARD_APP_UART_TX_DMA_REQ HPM_DMA_SRC_UART1_TX +#endif + +#define BOARD_APP_UART_BREAK_SIGNAL_PIN IOC_PAD_PF27 + +/* uart rx idle demo section */ +#define BOARD_UART_IDLE BOARD_APP_UART_BASE +#define BOARD_UART_IDLE_IRQ BOARD_APP_UART_IRQ +#define BOARD_UART_IDLE_CLK_NAME BOARD_APP_UART_CLK_NAME +#define BOARD_UART_IDLE_TX_DMA_SRC BOARD_APP_UART_TX_DMA_REQ +#define BOARD_UART_IDLE_DMA_SRC BOARD_APP_UART_RX_DMA_REQ + +#define BOARD_UART_IDLE_GPTMR HPM_GPTMR4 +#define BOARD_UART_IDLE_GPTMR_CLK_NAME clock_gptmr4 +#define BOARD_UART_IDLE_GPTMR_IRQ IRQn_GPTMR4 +#define BOARD_UART_IDLE_GPTMR_CMP_CH 0 +#define BOARD_UART_IDLE_GPTMR_CAP_CH 2 + +/* uart microros sample section */ +#define BOARD_MICROROS_UART_BASE BOARD_APP_UART_BASE +#define BOARD_MICROROS_UART_IRQ BOARD_APP_UART_IRQ +#define BOARD_MICROROS_UART_CLK_NAME BOARD_APP_UART_CLK_NAME + +/* enet section */ +#define BOARD_ENET_PPS HPM_ENET0 +#define BOARD_ENET_PPS_IDX enet_pps_0 +#define BOARD_ENET_PPS_PTP_CLOCK clock_ptp0 +#define BOARD_ENET_RMII HPM_ENET0 +#define BOARD_ENET_RMII_RST_GPIO +#define BOARD_ENET_RMII_RST_GPIO_INDEX +#define BOARD_ENET_RMII_RST_GPIO_PIN +#define BOARD_ENET_RMII HPM_ENET0 +#define BOARD_ENET_RMII_INT_REF_CLK (1U) +#define BOARD_ENET_RMII_PTP_CLOCK (clock_ptp0) +#define BOARD_ENET_RMII_PPS0_PINOUT (1) + +#define BOARD_ENET0_INF (1U) /* 0: RMII, 1: RGMII */ +#define BOARD_ENET0_INT_REF_CLK (0U) +#define BOARD_ENET0_PHY_RST_TIME (30) +#if BOARD_ENET0_INF +#define BOARD_ENET0_TX_DLY (0U) +#define BOARD_ENET0_RX_DLY (0U) +#endif +#if __USE_ENET_PTP +#define BOARD_ENET0_PTP_CLOCK (clock_ptp0) +#endif + +/* usb cdc acm uart section */ +#define BOARD_USB_CDC_ACM_UART BOARD_APP_UART_BASE +#define BOARD_USB_CDC_ACM_UART_CLK_NAME BOARD_APP_UART_CLK_NAME +#define BOARD_USB_CDC_ACM_UART_TX_DMA_SRC BOARD_APP_UART_TX_DMA_REQ +#define BOARD_USB_CDC_ACM_UART_RX_DMA_SRC BOARD_APP_UART_RX_DMA_REQ + +/* uart lin sample section */ +#define BOARD_UART_LIN BOARD_APP_UART_BASE +#define BOARD_UART_LIN_IRQ BOARD_APP_UART_IRQ +#define BOARD_UART_LIN_CLK_NAME BOARD_APP_UART_CLK_NAME +#define BOARD_UART_LIN_TX_PORT GPIO_DI_GPIOC +#define BOARD_UART_LIN_TX_PIN (23U) /* PC23 should align with used pin in pinmux configuration */ + +#if !defined(CONFIG_NDEBUG_CONSOLE) || !CONFIG_NDEBUG_CONSOLE +#ifndef BOARD_CONSOLE_TYPE +#define BOARD_CONSOLE_TYPE CONSOLE_TYPE_UART +#endif + +#if BOARD_CONSOLE_TYPE == CONSOLE_TYPE_UART +#ifndef BOARD_CONSOLE_UART_BASE +#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_UART1 +#define BOARD_CONSOLE_UART_CLK_NAME clock_uart1 +#define BOARD_CONSOLE_UART_IRQ IRQn_UART1 +#define BOARD_CONSOLE_UART_TX_DMA_REQ HPM_DMA_SRC_UART1_TX +#define BOARD_CONSOLE_UART_RX_DMA_REQ HPM_DMA_SRC_UART1_RX +#endif +#endif +#define BOARD_CONSOLE_UART_BAUDRATE (115200UL) +#endif +#endif + +/* rtthread-nano finsh section */ +#define BOARD_RT_CONSOLE_BASE BOARD_CONSOLE_UART_BASE + +/* modbus sample section */ +#define BOARD_MODBUS_UART_BASE BOARD_APP_UART_BASE +#define BOARD_MODBUS_UART_CLK_NAME BOARD_APP_UART_CLK_NAME +#define BOARD_MODBUS_UART_RX_DMA_REQ BOARD_APP_UART_RX_DMA_REQ +#define BOARD_MODBUS_UART_TX_DMA_REQ BOARD_APP_UART_TX_DMA_REQ + +/* 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_16_BITS +#define BOARD_SDRAM_REFRESH_COUNT (8192UL) +#define BOARD_SDRAM_REFRESH_IN_MS (64UL) + +/* nor flash section */ +#define BOARD_FLASH_BASE_ADDRESS (0x80000000UL) +#define BOARD_FLASH_SIZE (16 * SIZE_1MB) + +/* i2c section */ +#define BOARD_APP_I2C_BASE HPM_I2C0 +#define BOARD_APP_I2C_IRQ IRQn_I2C0 +#define BOARD_APP_I2C_CLK_NAME clock_i2c0 +#define BOARD_APP_I2C_DMA HPM_HDMA +#define BOARD_APP_I2C_DMAMUX HPM_DMAMUX +#define BOARD_APP_I2C_DMA_SRC HPM_DMA_SRC_I2C0 + +#define BOARD_APP_I2C_DMAMUX_CH DMAMUX_MUXCFG_HDMA_MUX0 +#define BOARD_I2C_GPIO_CTRL HPM_GPIO0 +#define BOARD_I2C_SCL_GPIO_INDEX GPIO_DO_GPIOY +#define BOARD_I2C_SCL_GPIO_PIN 2 +#define BOARD_I2C_SDA_GPIO_INDEX GPIO_DO_GPIOY +#define BOARD_I2C_SDA_GPIO_PIN 3 + +/* i2c for i2s codec section */ +#define BOARD_CODEC_I2C_BASE HPM_I2C1 +#define BOARD_CODEC_I2C_CLK_NAME clock_i2c1 + +/* i2s section */ +#define BOARD_APP_I2S_BASE HPM_I2S0 +#define BOARD_APP_I2S_DATA_LINE (0U) +#define BOARD_APP_I2S_CLK_NAME clock_i2s0 +#define BOARD_APP_AUDIO_CLK_SRC clock_source_pll2_clk0 +#define BOARD_APP_AUDIO_CLK_SRC_NAME clk_pll2clk0 +#define BOARD_APP_I2S_TX_DMA_REQ HPM_DMA_SRC_I2S0_TX +#define BOARD_APP_I2S_IRQ IRQn_I2S0 +#define BOARD_PDM_SINGLE_CHANNEL_MASK (1U) +#define BOARD_PDM_DUAL_CHANNEL_MASK (0x11U) + +/* dma section */ +#define BOARD_APP_XDMA HPM_XDMA +#define BOARD_APP_HDMA HPM_HDMA +#define BOARD_APP_XDMA_IRQ IRQn_XDMA +#define BOARD_APP_HDMA_IRQ IRQn_HDMA +#define BOARD_APP_DMAMUX HPM_DMAMUX +#define TEST_DMA_CONTROLLER HPM_HDMA +#define TEST_DMA_IRQ IRQn_HDMA + +/* APP PWM */ +#define BOARD_APP_PWM HPM_PWM1 +#define BOARD_APP_PWM_CLOCK_NAME clock_pwm1 +#define BOARD_APP_PWM_OUT1 pwm_channel_0 +#define BOARD_APP_PWM_OUT2 pwm_channel_1 +#define BOARD_APP_PWM_OUT3 pwm_channel_2 +#define BOARD_APP_PWM_OUT4 pwm_channel_3 +#define BOARD_APP_PWM_FAULT_PIN (5) +#define BOARD_APP_TRGM HPM_TRGM0 +#define BOARD_APP_PWM_IRQ IRQn_PWM1 +#define BOARD_APP_TRGM_PWM_OUTPUT HPM_TRGM0_OUTPUT_SRC_PWM1_TRIG_IN0 +#define BOARD_APP_TRGM_PWM_INPUT HPM_TRGM0_INPUT_SRC_PWM1_TRGO_0 + +/* gptmr section */ +#define BOARD_GPTMR HPM_GPTMR4 +#define BOARD_GPTMR_IRQ IRQn_GPTMR4 +#define BOARD_GPTMR_CHANNEL 0 +#define BOARD_GPTMR_DMA_SRC HPM_DMA_SRC_GPTMR4_0 +#define BOARD_GPTMR_CLK_NAME clock_gptmr4 +#define BOARD_GPTMR_PWM HPM_GPTMR4 +#define BOARD_GPTMR_PWM_CHANNEL 0 +#define BOARD_GPTMR_PWM_DMA_SRC HPM_DMA_SRC_GPTMR4_0 +#define BOARD_GPTMR_PWM_CLK_NAME clock_gptmr4 +#define BOARD_GPTMR_PWM_IRQ IRQn_GPTMR4 +#define BOARD_GPTMR_PWM_SYNC HPM_GPTMR0 +#define BOARD_GPTMR_PWM_SYNC_CHANNEL 0 +#define BOARD_GPTMR_PWM_SYNC_CLK_NAME clock_gptmr0 + +/* User button */ +#define BOARD_APP_GPIO_CTRL HPM_GPIO0 +#define BOARD_APP_GPIO_INDEX GPIO_DI_GPIOB +#define BOARD_APP_GPIO_PIN 24 +#define BOARD_APP_GPIO_IRQ IRQn_GPIO0_B + +#define BOARD_APP_GPIO_CTRL2 HPM_GPIO0 +#define BOARD_APP_GPIO_INDEX2 GPIO_DI_GPIOB +#define BOARD_APP_GPIO_PIN2 25 +#define BOARD_APP_GPIO_IRQ2 IRQn_GPIO0_B + +/* gpiom section */ +#define BOARD_APP_GPIOM_BASE HPM_GPIOM +#define BOARD_APP_GPIOM_USING_CTRL HPM_FGPIO +#define BOARD_APP_GPIOM_USING_CTRL_NAME gpiom_core0_fast + +/* spi section */ +#define BOARD_APP_SPI_BASE HPM_SPI7 +#define BOARD_APP_SPI_CLK_NAME clock_spi7 +#define BOARD_APP_SPI_IRQ IRQn_SPI7 +#define BOARD_APP_SPI_SCLK_FREQ (20000000UL) +#define BOARD_APP_SPI_ADDR_LEN_IN_BYTES (1U) +#define BOARD_APP_SPI_DATA_LEN_IN_BITS (8U) +#define BOARD_APP_SPI_RX_DMA HPM_DMA_SRC_SPI7_RX +#define BOARD_APP_SPI_TX_DMA HPM_DMA_SRC_SPI7_TX +#define BOARD_SPI_CS_GPIO_CTRL HPM_GPIO0 +#define BOARD_SPI_CS_PIN IOC_PAD_PF27 +#define BOARD_SPI_CS_ACTIVE_LEVEL (0U) + +/* Flash section */ +#define BOARD_APP_XPI_NOR_XPI_BASE (HPM_XPI0) +#define BOARD_APP_XPI_NOR_CFG_OPT_HDR (0xfcf90001U) +#define BOARD_APP_XPI_NOR_CFG_OPT_OPT0 (0x00000005U) +#define BOARD_APP_XPI_NOR_CFG_OPT_OPT1 (0x00001000U) + +/* ADC section */ +#define BOARD_APP_ADC16_NAME "ADC0" +#define BOARD_APP_ADC16_BASE HPM_ADC0 +#define BOARD_APP_ADC16_IRQn IRQn_ADC0 +#define BOARD_APP_ADC16_CH_1 (15U) +#define BOARD_APP_ADC16_CLK_NAME (clock_adc0) + +#define BOARD_APP_ADC16_HW_TRIG_SRC_CLK_NAME clock_pwm0 +#define BOARD_APP_ADC16_HW_TRIG_SRC HPM_PWM0 +#define BOARD_APP_ADC16_HW_TRGM HPM_TRGM0 +#define BOARD_APP_ADC16_HW_TRGM_IN HPM_TRGM0_INPUT_SRC_PWM0_TRGO_0 +#define BOARD_APP_ADC16_HW_TRGM_OUT_SEQ TRGM_TRGOCFG_ADC0_STRGI +#define BOARD_APP_ADC16_HW_TRGM_OUT_PMT TRGM_TRGOCFG_ADCX_PTRGI0A +#define BOARD_APP_ADC16_PMT_TRIG_CH ADC16_CONFIG_TRG0A + +/* CAN section */ +#define BOARD_APP_CAN_BASE HPM_MCAN4 +#define BOARD_APP_CAN_IRQn IRQn_MCAN4 + +/* + * timer for board delay + */ +#define BOARD_DELAY_TIMER (HPM_GPTMR3) +#define BOARD_DELAY_TIMER_CH 0 +#define BOARD_DELAY_TIMER_CLK_NAME (clock_gptmr3) + +#define BOARD_CALLBACK_TIMER (HPM_GPTMR3) +#define BOARD_CALLBACK_TIMER_CH 1 +#define BOARD_CALLBACK_TIMER_IRQ IRQn_GPTMR3 +#define BOARD_CALLBACK_TIMER_CLK_NAME (clock_gptmr3) + +/* USB section */ +#define BOARD_USB HPM_USB0 + +/* LED */ +#define BOARD_R_GPIO_CTRL HPM_GPIO0 +#define BOARD_R_GPIO_INDEX GPIO_DI_GPIOE +#define BOARD_R_GPIO_PIN 14 +#define BOARD_G_GPIO_CTRL HPM_GPIO0 +#define BOARD_G_GPIO_INDEX GPIO_DI_GPIOE +#define BOARD_G_GPIO_PIN 15 +#define BOARD_B_GPIO_CTRL HPM_GPIO0 +#define BOARD_B_GPIO_INDEX GPIO_DI_GPIOE +#define BOARD_B_GPIO_PIN 4 + +#define BOARD_LED_GPIO_CTRL HPM_GPIO0 +#define BOARD_LED_GPIO_INDEX GPIO_DI_GPIOE +#define BOARD_LED_GPIO_PIN 15 +#define BOARD_LED_OFF_LEVEL 0 +#define BOARD_LED_ON_LEVEL 1 + +#define BOARD_LED_TOGGLE_RGB 1 + +/* RGB LED Section */ +#define BOARD_RED_PWM_IRQ IRQn_PWM1 +#define BOARD_RED_PWM HPM_PWM1 +#define BOARD_RED_PWM_OUT_CH 6 +#define BOARD_RED_PWM_SHADOW_ID 1 +#define BOARD_RED_PWM_CMP_ID 6 +#define BOARD_RED_PWM_COUNTER_INDEX 2 +#define BOARD_RED_PWM_CMP_INITIAL_ZERO true +#define BOARD_RED_PWM_CLOCK_NAME clock_mot1 + +#define BOARD_GREEN_PWM_IRQ IRQn_PWM1 +#define BOARD_GREEN_PWM HPM_PWM1 +#define BOARD_GREEN_PWM_OUT_CH 7 +#define BOARD_GREEN_PWM_SHADOW_ID 2 +#define BOARD_GREEN_PWM_CMP_ID 7 +#define BOARD_GREEN_PWM_COUNTER_INDEX 2 +#define BOARD_GREEN_PWM_CMP_INITIAL_ZERO true +#define BOARD_GREEN_PWM_CLOCK_NAME clock_mot1 + +#define BOARD_BLUE_PWM_IRQ IRQn_PWM0 +#define BOARD_BLUE_PWM HPM_PWM0 +#define BOARD_BLUE_PWM_OUT_CH 4 +#define BOARD_BLUE_PWM_SHADOW_ID 3 +#define BOARD_BLUE_PWM_CMP_ID 4 +#define BOARD_BLUE_PWM_COUNTER_INDEX 1 +#define BOARD_BLUE_PWM_CMP_INITIAL_ZERO true +#define BOARD_BLUE_PWM_CLOCK_NAME clock_mot0 + +#define BOARD_RGB_RED 0 +#define BOARD_RGB_GREEN (BOARD_RGB_RED + 1) +#define BOARD_RGB_BLUE (BOARD_RGB_RED + 2) + +/* pdma section */ +#define BOARD_PDMA_BASE HPM_PDMA + +#ifndef BOARD_SHOW_CLOCK +#define BOARD_SHOW_CLOCK 1 +#endif +#ifndef BOARD_SHOW_BANNER +#define BOARD_SHOW_BANNER 1 +#endif + +/* enet section */ +#define BOARD_ENET_RGMII_RST_GPIO HPM_GPIO0 +#define BOARD_ENET_RGMII_RST_GPIO_INDEX GPIO_DO_GPIOA +#define BOARD_ENET_RGMII_RST_GPIO_PIN (14U) + +#define BOARD_ENET_RGMII HPM_ENET0 +#define BOARD_ENET_RGMII_TX_DLY (0U) +#define BOARD_ENET_RGMII_RX_DLY (0U) + +#define BOARD_ENET_RGMII_PTP_CLOCK (clock_ptp0) + +/* TSW section */ +#define BOARD_TSW HPM_TSW + +/* MOTOR */ +#define BOARD_MOTOR_CLK_NAME clock_mot0 + +/*BLDC PWM */ +#define BOARD_BLDCPWM HPM_PWM1 +#define BOARD_BLDC_UH_PWM_OUTPIN (pwm_channel_0) +#define BOARD_BLDC_UL_PWM_OUTPIN (pwm_channel_1) +#define BOARD_BLDC_VH_PWM_OUTPIN (pwm_channel_2) +#define BOARD_BLDC_VL_PWM_OUTPIN (pwm_channel_3) +#define BOARD_BLDC_WH_PWM_OUTPIN (pwm_channel_4) +#define BOARD_BLDC_WL_PWM_OUTPIN (pwm_channel_5) +#define BOARD_BLDCPWM_TRGM HPM_TRGM0 +#define BOARD_BLDCAPP_PWM_IRQ IRQn_PWM1 +#define BOARD_BLDCPWM_CMP_INDEX_0 (0U) +#define BOARD_BLDCPWM_CMP_INDEX_1 (1U) +#define BOARD_BLDCPWM_CMP_INDEX_2 (2U) +#define BOARD_BLDCPWM_CMP_INDEX_3 (3U) +#define BOARD_BLDCPWM_CMP_INDEX_4 (4U) +#define BOARD_BLDCPWM_CMP_INDEX_5 (5U) +#define BOARD_BLDCPWM_CMP_INDEX_6 (6U) +#define BOARD_BLDCPWM_CMP_INDEX_7 (7U) +#define BOARD_BLDCPWM_CMP_TRIG_CMP (16U) + +#define BOARD_BLDC_TMR_1MS HPM_GPTMR2 +#define BOARD_BLDC_TMR_CH 0 +#define BOARD_BLDC_TMR_CMP 0 +#define BOARD_BLDC_TMR_IRQ IRQn_GPTMR2 +#define BOARD_BLDC_TMR_RELOAD (100000U) + +/* BLDC ADC */ +#define BOARD_BLDC_ADC_MODULE ADCX_MODULE_ADC16 +#define BOARD_BLDC_ADC_U_BASE HPM_ADC0 +#define BOARD_BLDC_ADC_V_BASE HPM_ADC1 +#define BOARD_BLDC_ADC_W_BASE HPM_ADC2 +#define BOARD_BLDC_ADC_TRIG_FLAG adc16_event_trig_complete + +#define BOARD_BLDC_ADC_CH_U (14U) +#define BOARD_BLDC_ADC_CH_V (10U) +#define BOARD_BLDC_ADC_CH_W (11U) +#define BOARD_BLDC_ADC_IRQn IRQn_ADC0 +#define BOARD_BLDC_ADC_PMT_DMA_SIZE_IN_4BYTES (ADC_SOC_PMT_MAX_DMA_BUFF_LEN_IN_4BYTES) +#define BOARD_BLDC_ADC_TRG ADC16_CONFIG_TRG0A +#define BOARD_BLDC_ADC_PREEMPT_TRIG_LEN (1U) +#define BOARD_BLDC_TRG_NUM TRGM_TRGOCFG_ADCX_PTRGI0A +#define BOARD_BLDC_PWM_TRIG_OUT_CHN (0U) + +/* BLDC TRGM */ +#define BOARD_BLDC_TRIGMUX_IN_NUM HPM_TRGM0_INPUT_SRC_PWM1_TRGO_0 +#define BOARD_BLDC_TRIGMUX_OUT_NUM_ADC HPM_TRGM0_OUTPUT_SRC_ADCX_PTRGI0A +#define BOARD_BLDC_TRIGMUX_OUT_NUM_VSC HPM_TRGM0_OUTPUT_SRC_VSC0_TRIG_IN0 + +#define BOARD_BLDC_TRGM_ADC_MATRIX_TO_VSC_ADC0 trgm_adc_matrix_output_to_vsc0_adc0 +#define BOARD_BLDC_TRGM_ADC_MATRIX_TO_VSC_ADC1 trgm_adc_matrix_output_to_vsc0_adc1 +#define BOARD_BLDC_TRGM_ADC_MATRIX_TO_VSC_ADC2 trgm_adc_matrix_output_to_vsc0_adc2 +#define BOARD_BLDC_TRGM_ADC_MATRIX_FROM_ADC_U trgm_adc_matrix_in_from_adc0 +#define BOARD_BLDC_TRGM_ADC_MATRIX_FROM_ADC_V trgm_adc_matrix_in_from_adc1 +#define BOARD_BLDC_TRGM_ADC_MATRIX_FROM_ADC_W trgm_adc_matrix_in_from_adc2 + +#define BOARD_BLDC_TRGM_ADC_MATRIX_TO_CLC_ID_ADC trgm_adc_matrix_output_to_clc0_id_adc +#define BOARD_BLDC_TRGM_ADC_MATRIX_TO_CLC_IQ_ADC trgm_adc_matrix_output_to_clc0_iq_adc +#define BOARD_BLDC_TRGM_ADC_MATRIX_FROM_VSC_ID_ADC trgm_adc_matrix_in_from_vsc0_id_adc +#define BOARD_BLDC_TRGM_ADC_MATRIX_FROM_VSC_IQ_ADC trgm_adc_matrix_in_from_vsc0_iq_adc + +#define BOARD_BLDC_TRGM_DAC_MATRIX_TO_QEO_VD_DAC trgm_dac_matrix_output_to_qeo0_vd_dac +#define BOARD_BLDC_TRGM_DAC_MATRIX_TO_QEO_VQ_DAC trgm_dac_matrix_output_to_qeo0_vq_dac +#define BOARD_BLDC_TRGM_DAC_MATRIX_FROM_CLC_VD_DAC trgm_dac_matrix_in_from_clc0_vd_dac +#define BOARD_BLDC_TRGM_DAC_MATRIX_FROM_CLC_VQ_DAC trgm_dac_matrix_in_from_clc0_vq_dac + +#define BOARD_BLDC_TRGM_DAC_MATRIX_TO_PWM_DAC0 trgm_dac_matrix_output_to_pwm1_dac0 +#define BOARD_BLDC_TRGM_DAC_MATRIX_TO_PWM_DAC1 trgm_dac_matrix_output_to_pwm1_dac1 +#define BOARD_BLDC_TRGM_DAC_MATRIX_TO_PWM_DAC2 trgm_dac_matrix_output_to_pwm1_dac2 +#define BOARD_BLDC_TRGM_DAC_MATRIX_FROM_QEO_DAC0 trgm_dac_matrix_in_from_qeo0_dac0 +#define BOARD_BLDC_TRGM_DAC_MATRIX_FROM_QEO_DAC1 trgm_dac_matrix_in_from_qeo0_dac1 +#define BOARD_BLDC_TRGM_DAC_MATRIX_FROM_QEO_DAC2 trgm_dac_matrix_in_from_qeo0_dac2 + +#define BOARD_BLDC_TRGM_POS_MATRIX_TO_VSC trgm_pos_matrix_output_to_vsc0 +#define BOARD_BLDC_TRGM_POS_MATRIX_TO_QEO trgm_pos_matrix_output_to_qeo0 +#define BOARD_BLDC_TRGM_POS_MATRIX_FROM_QEI trgm_pos_matrix_in_from_qei0 + +/* BLDC TIMER */ +#define BOARD_BLDC_TMR_BASE HPM_GPTMR2 +#define BOARD_BLDC_TMR_CH 0 +#define BOARD_BLDC_TMR_IRQ IRQn_GPTMR2 +#define BOARD_BLDC_TMR_CLOCK clock_gptmr2 +#define BOARD_BLDC_TMR_PERIOD_MS (1u) + +/* HALL */ + +/* RDC */ +#define BOARD_RDC_BASE HPM_RDC0 +#define BOARD_RDC_TRGM HPM_TRGM0 +#define BOARD_RDC_TRGIGMUX_IN_NUM HPM_TRGM0_INPUT_SRC_RDC0_TRGO_0 +#define BOARD_RDC_TRG_NUM TRGM_TRGOCFG_MOT_GPIO0 +#define BOARD_RDC_TRG_ADC_NUM HPM_TRGM0_OUTPUT_SRC_ADCX_PTRGI0A +#define BOARD_RDC_ADC_I_BASE HPM_ADC0 +#define BOARD_RDC_ADC_Q_BASE HPM_ADC1 +#define BOARD_RDC_ADC_I_CHN (14U) +#define BOARD_RDC_ADC_Q_CHN (10U) +#define BOARD_RDC_ADC_IRQn IRQn_ADC0 +#define BOARD_RDC_ADC_TRIG_FLAG adc16_event_trig_complete +#define BOARD_RDC_ADC_TRG ADC16_CONFIG_TRG0A +#define BOARD_APP_RDC_ADC_MATRIX_TO_ADC0 trgm_adc_matrix_output_to_rdc0_adc0 +#define BOARD_APP_RDC_ADC_MATRIX_TO_ADC1 trgm_adc_matrix_output_to_rdc0_adc1 +#define BOARD_APP_RDC_ADC_MATRIX_FROM_ADC_I trgm_adc_matrix_in_from_adc0 +#define BOARD_APP_RDC_ADC_MATRIX_FROM_ADC_Q trgm_adc_matrix_in_from_adc1 + +/* QEIV2 */ +#define BOARD_BLDC_QEI_TRGM HPM_TRGM0 +#define BOARD_BLDC_QEIV2_BASE HPM_QEI0 +#define BOARD_BLDC_QEIV2_IRQ IRQn_QEI0 +#define BOARD_BLDC_QEI_MOTOR_PHASE_COUNT_PER_REV (16U) +#define BOARD_BLDC_QEI_CLOCK_SOURCE clock_qei0 +#define BOARD_BLDC_QEI_FOC_PHASE_COUNT_PER_REV (4000U) + +#define BOARD_APP_QEIV2_BASE HPM_QEI3 +#define BOARD_APP_QEIV2_IRQ IRQn_QEI3 +#define BOARD_APP_QEI_CLOCK_SOURCE clock_qei3 +#define BOARD_APP_QEI_ADC_COS_BASE HPM_ADC2 +#define BOARD_APP_QEI_ADC_COS_CHN (11U) +#define BOARD_APP_QEI_ADC_SIN_BASE HPM_ADC0 +#define BOARD_APP_QEI_ADC_SIN_CHN (14U) +#define BOARD_APP_QEI_ADC_MATRIX_TO_ADC0 trgm_adc_matrix_output_to_qei3_adc0 +#define BOARD_APP_QEI_ADC_MATRIX_TO_ADC1 trgm_adc_matrix_output_to_qei3_adc1 +#define BOARD_APP_QEI_ADC_MATRIX_FROM_ADC_COS trgm_adc_matrix_in_from_adc2 +#define BOARD_APP_QEI_ADC_MATRIX_FROM_ADC_SIN trgm_adc_matrix_in_from_adc0 + +/* PLB */ +#define BOARD_PLB_COUNTER HPM_PLB +#define BOARD_PLB_PWM_BASE HPM_PWM0 +#define BOARD_PLB_PWM_CLOCK_NAME clock_mot0 +#define BOARD_PLB_TRGM HPM_TRGM0 +#define BOARD_PLB_PWM_TRG (HPM_TRGM0_INPUT_SRC_PWM0_TRGO_0) +#define BOARD_PLB_IN_PWM_TRG_NUM (TRGM_TRGOCFG_PLB_IN_00) +#define BOARD_PLB_IN_PWM_PULSE_TRG_NUM (TRGM_TRGOCFG_PLB_IN_02) +#define BOARD_PLB_CLR_SIGNAL_INPUT (HPM_TRGM0_INPUT_SRC_PLB_OUT32) +#define BOARD_PLB_TYPEB_INPUT0 (TRGM_TRGOCFG_PLB_IN_32) +#define BOARD_PLB_OUT_TRG (HPM_TRGM0_INPUT_SRC_PLB_OUT00) +#define BOARD_PLB_IO_TRG_NUM (TRGM_TRGOCFG_MOT_GPIO5) +#define BOARD_PLB_IO_TRG_SHIFT (5) +#define BOARD_PLB_PWM_CMP (8U) +#define BOARD_PLB_PWM_CHN (8U) +#define BOARD_PLB_CHN plb_chn0 + +/* QEO */ +#define BOARD_QEO HPM_QEO0 +#define BOARD_QEO_TRGM_POS trgm_pos_matrix_output_to_qeo0 + +#define BOARD_QEO_PWM HPM_QEO1 /*QEO instance should align with PWM instance, such as QEO1 -> PWM1 */ +#define BOARD_QEO_TRGM_POS_PWM trgm_pos_matrix_output_to_qeo1 + +/* SEI */ +#define BOARD_SEI HPM_SEI +#define BOARD_SEI_CTRL SEI_CTRL_1 +#define BOARD_SEI_IRQn IRQn_SEI_1 +#define BOARD_TRGM_POS_SOURCE_SEI trgm_pos_matrix_in_from_sei_pos1 + +/* MTG */ +#define BOARD_TRGM_POS_DEST_MTG trgm_pos_matrix_output_to_mtg0 + +/* VSC */ +#define BOARD_VSC HPM_VSC0 +#define BOARD_VSC_IRQn IRQn_VSC0 + +/* CLC */ +#define BOARD_CLC HPM_CLC0 +#define BOARD_CLC_IRQn IRQn_CLC0_0 + +/* Tamper Section */ +#define BOARD_TAMP_ACTIVE_CH 4 +#define BOARD_TAMP_LOW_LEVEL_CH 3 + +/* sdm section */ +#define BOARD_SDM HPM_SDM0 +#define BOARD_SDM_IRQ IRQn_SDM0 +#define BOARD_SDM_CHANNEL 0 +#define BOARD_SDM_TRGM HPM_TRGM0 +#define BOARD_SDM_TRGM_GPTMR HPM_GPTMR3 +#define BOARD_SDM_TRGM_GPTMR_CH 2 +#define BOARD_SDM_TRGM_INPUT_SRC HPM_TRGM0_INPUT_SRC_GPTMR3_OUT2 +#define BOARD_SDM_TRGM_OUTPUT_DST HPM_TRGM0_OUTPUT_SRC_SDM_PWM_SOC15 +#define BOARD_SDM_TRGM_SYNC_SRC (15) +/* need to provide clock to sdm sensor */ +#define BOARD_SDM_SENSOR_REQUIRE_CLK true +#define BOARD_SDM_CLK_PWM HPM_PWM2 +#define BOARD_SDM_CLK_PWM_CLK_NAME clock_pwm2 +#define BOARD_SDM_CLK_PWM_OUT (3) + + + +/* EtherCAT definitions */ +/* ECAT PORT0 must support */ +#define BOARD_ECAT_SUPPORT_PORT1 (1) +#define BOARD_ECAT_SUPPORT_PORT2 (0) + +#define BOARD_ECAT_PHY0_RESET_GPIO HPM_GPIO0 +#define BOARD_ECAT_PHY0_RESET_GPIO_PORT_INDEX GPIO_DO_GPIOA +#define BOARD_ECAT_PHY0_RESET_PIN_INDEX (10) + +#define BOARD_ECAT_PHY1_RESET_GPIO HPM_GPIO0 +#define BOARD_ECAT_PHY1_RESET_GPIO_PORT_INDEX GPIO_DO_GPIOA +#define BOARD_ECAT_PHY1_RESET_PIN_INDEX (10) +#define BOARD_ECAT_PHY_RESET_LEVEL (0) + +#define BOARD_ECAT_IN1_GPIO HPM_GPIO0 +#define BOARD_ECAT_IN1_GPIO_PORT_INDEX GPIO_DO_GPIOC +#define BOARD_ECAT_IN1_GPIO_PIN_INDEX (31U) + +#define BOARD_ECAT_IN2_GPIO HPM_GPIO0 +#define BOARD_ECAT_IN2_GPIO_PORT_INDEX GPIO_DO_GPIOD +#define BOARD_ECAT_IN2_GPIO_PIN_INDEX (9U) + +#define BOARD_ECAT_OUT1_GPIO HPM_GPIO0 +#define BOARD_ECAT_OUT1_GPIO_PORT_INDEX GPIO_DO_GPIOD +#define BOARD_ECAT_OUT1_GPIO_PIN_INDEX (8U) + +#define BOARD_ECAT_OUT2_GPIO BOARD_R_GPIO_CTRL /* reuse RGB red led */ +#define BOARD_ECAT_OUT2_GPIO_PORT_INDEX BOARD_R_GPIO_INDEX +#define BOARD_ECAT_OUT2_GPIO_PIN_INDEX BOARD_R_GPIO_PIN + +#define BOARD_ECAT_OUT_ON_LEVEL (1) /* ECAT control LED on level */ + +#define BOARD_ECAT_NMII_LINK0_CTRL_INDEX 3 +#define BOARD_ECAT_NMII_LINK1_CTRL_INDEX 0 +#define BOARD_ECAT_LED_RUN_CTRL_INDEX 1 +#define BOARD_ECAT_LED_ERROR_CTRL_INDEX 6 + +#ifndef BOARD_SHOW_CLOCK +#define BOARD_SHOW_CLOCK 1 +#endif +#ifndef BOARD_SHOW_BANNER +#define BOARD_SHOW_BANNER 1 +#endif + +/* FreeRTOS Definitions */ +#define BOARD_FREERTOS_TIMER HPM_GPTMR6 +#define BOARD_FREERTOS_TIMER_CHANNEL 1 +#define BOARD_FREERTOS_TIMER_IRQ IRQn_GPTMR6 +#define BOARD_FREERTOS_TIMER_CLK_NAME clock_gptmr6 + +#define BOARD_FREERTOS_LOWPOWER_TIMER HPM_PTMR +#define BOARD_FREERTOS_LOWPOWER_TIMER_CHANNEL 1 +#define BOARD_FREERTOS_LOWPOWER_TIMER_IRQ IRQn_PTMR +#define BOARD_FREERTOS_LOWPOWER_TIMER_CLK_NAME clock_ptmr +/* Threadx Definitions */ +#define BOARD_THREADX_TIMER HPM_GPTMR6 +#define BOARD_THREADX_TIMER_CHANNEL 1 +#define BOARD_THREADX_TIMER_IRQ IRQn_GPTMR6 +#define BOARD_THREADX_TIMER_CLK_NAME clock_gptmr6 + +#define BOARD_THREADX_LOWPOWER_TIMER HPM_PTMR +#define BOARD_THREADX_LOWPOWER_TIMER_CHANNEL 1 +#define BOARD_THREADX_LOWPOWER_TIMER_IRQ IRQn_PTMR +#define BOARD_THREADX_LOWPOWER_TIMER_CLK_NAME clock_ptmr + +/* LOBS */ +#define BOARD_LOBS_TRIG_GROUP 5 /* group5 <--> PF */ +#define BOARD_LOBS_TRIG_PIN 26 + +/* i2s over spi Section*/ +#define BOARD_I2S_SPI_CS_GPIO_CTRL HPM_GPIO0 +#define BOARD_I2S_SPI_CS_GPIO_INDEX GPIO_DI_GPIOE +#define BOARD_I2S_SPI_CS_GPIO_PIN 6 +#define BOARD_I2S_SPI_CS_GPIO_PAD IOC_PAD_PA06 + +#define BOARD_GPTMR_I2S_MCLK HPM_GPTMR5 +#define BOARD_GPTMR_I2S_MCLK_CHANNEL 2 +#define BOARD_GPTMR_I2S_MCLK_CLK_NAME clock_gptmr5 + +#define BOARD_GPTMR_I2S_LRCK HPM_GPTMR4 +#define BOARD_GPTMR_I2S_LRCK_CHANNEL 0 +#define BOARD_GPTMR_I2S_LRCK_CLK_NAME clock_gptmr4 + +#define BOARD_GPTMR_I2S_BCLK HPM_GPTMR0 +#define BOARD_GPTMR_I2S_BLCK_CHANNEL 0 +#define BOARD_GPTMR_I2S_BLCK_CLK_NAME clock_gptmr0 + +#define BOARD_GPTMR_I2S_FINSH HPM_GPTMR0 +#define BOARD_GPTMR_I2S_FINSH_IRQ IRQn_GPTMR0 +#define BOARD_GPTMR_I2S_FINSH_CHANNEL 1 +#define BOARD_GPTMR_I2S_FINSH_CLK_NAME clock_gptmr0 + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +typedef void (*board_timer_cb)(void); + +void board_init(void); +void board_init_console(void); +void board_init_core1(void); +void board_init_uart(UART_Type *ptr); +void board_init_i2c(I2C_Type *ptr); +void board_init_can(MCAN_Type *ptr); +void board_init_sdram_pins(void); +void board_init_gpio_pins(void); +void board_init_spi_pins(SPI_Type *ptr); +void board_init_spi_pins_with_gpio_as_cs(SPI_Type *ptr); +void board_write_spi_cs(uint32_t pin, uint8_t state); +uint8_t board_get_led_gpio_off_level(void); +void board_init_led_pins(void); +void board_led_write(uint8_t state); +void board_led_toggle(void); + +/* Initialize SoC overall clocks */ +void board_init_clock(void); +uint32_t board_init_femc_clock(void); +uint32_t board_init_uart_clock(UART_Type *ptr); +uint32_t board_init_spi_clock(SPI_Type *ptr); +uint32_t board_init_can_clock(MCAN_Type *ptr); +uint32_t board_init_adc16_clock(void *ptr, bool clk_src_ahb); +void board_init_i2s_pins(I2S_Type *ptr); +uint32_t board_config_i2s_clock(I2S_Type *ptr, uint32_t sample_rate); +uint32_t board_init_pdm_clock(void); +uint32_t board_init_dao_clock(void); +void board_init_dao_pins(void); +void board_init_adc16_pins(void); +void board_init_usb_pins(void); +void board_usb_vbus_ctrl(uint8_t usb_index, uint8_t level); +void board_init_enet_pps_pins(ENET_Type *ptr); +uint8_t board_get_enet_dma_pbl(ENET_Type *ptr); +hpm_stat_t board_reset_enet_phy(ENET_Type *ptr); +hpm_stat_t board_init_enet_pins(ENET_Type *ptr); +hpm_stat_t board_init_enet_rmii_reference_clock(ENET_Type *ptr, bool internal); +hpm_stat_t board_init_enet_rgmii_clock_delay(ENET_Type *ptr); +hpm_stat_t board_init_enet_ptp_clock(ENET_Type *ptr); +hpm_stat_t board_enable_enet_irq(ENET_Type *ptr); +hpm_stat_t board_disable_enet_irq(ENET_Type *ptr); + +/* + * @brief Initialize PMP and PMA for but not limited to the following purposes: + * -- non-cacheable memory initialization + */ +void board_init_pmp(void); +void board_delay_us(uint32_t us); +void board_delay_ms(uint32_t ms); +void board_timer_create(uint32_t ms, board_timer_cb cb); +void board_ungate_mchtmr_at_lp_mode(void); + +/* + * Get GPIO pin level of onboard LED + */ +uint8_t board_get_led_gpio_off_level(void); +void board_init_ethercat(ESC_Type *ptr); +void board_init_switch_led(void); +void board_init_tsw(TSW_Type *ptr); +void board_init_sei_pins(SEI_Type *ptr, uint8_t sei_ctrl_idx); +void board_init_adc_qeiv2_pins(void); + +uint32_t board_init_gptmr_clock(GPTMR_Type *ptr); +uint32_t board_init_pwm_clock(PWMV2_Type *ptr); +#if defined(__cplusplus) +} +#endif /* __cplusplus */ +#endif /* _HPM_BOARD_H */ diff --git a/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/boards/hpm6e00evk.cfg b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/boards/hpm6e00evk.cfg new file mode 100644 index 0000000000..3147f1b559 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/boards/hpm6e00evk.cfg @@ -0,0 +1,80 @@ +# Copyright (c) 2024 HPMicro +# SPDX-License-Identifier: BSD-3-Clause + +# openocd flash driver argument: +# - option0: +# [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 +# - option1: +# [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 + +# xpi0 configs +# - flash driver: hpm_xpi +# - flash ctrl index: 0xF3000000 +# - base address: 0x80000000 +# - flash size: 0x2000000 +# - flash option0: 0x7 +flash bank xpi0 hpm_xpi 0x80000000 0x2000000 1 1 $_TARGET0 0xF3000000 0x7 + +proc init_clock {} { + $::_TARGET0 riscv dmi_write 0x39 0xF4002000 + $::_TARGET0 riscv dmi_write 0x3C 0x1 + + $::_TARGET0 riscv dmi_write 0x39 0xF4002000 + $::_TARGET0 riscv dmi_write 0x3C 0x2 + + $::_TARGET0 riscv dmi_write 0x39 0xF4000800 + $::_TARGET0 riscv dmi_write 0x3C 0xFFFFFFFF + + $::_TARGET0 riscv dmi_write 0x39 0xF4000810 + $::_TARGET0 riscv dmi_write 0x3C 0xFFFFFFFF + + $::_TARGET0 riscv dmi_write 0x39 0xF4000820 + $::_TARGET0 riscv dmi_write 0x3C 0xFFFFFFFF + + $::_TARGET0 riscv dmi_write 0x39 0xF4000830 + $::_TARGET0 riscv dmi_write 0x3C 0xFFFFFFFF + echo "clocks has been enabled!" +} + + +$_TARGET0 configure -event reset-init { + init_clock +} + +$_TARGET0 configure -event gdb-attach { + reset halt +} diff --git a/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/cmsis_dap.cfg b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/cmsis_dap.cfg new file mode 100644 index 0000000000..b9ae112104 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/cmsis_dap.cfg @@ -0,0 +1,11 @@ +# Copyright 2021 hpmicro +# SPDX-License-Identifier: BSD-3-Clause + +bindto 0.0.0.0 +adapter speed 10000 +adapter srst delay 500 + +source [find interface/cmsis-dap.cfg] + +transport select jtag +reset_config srst_only diff --git a/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/ft2232.cfg b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/ft2232.cfg new file mode 100644 index 0000000000..580d98ef85 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/ft2232.cfg @@ -0,0 +1,15 @@ +# Copyright 2021 hpmicro +# SPDX-License-Identifier: BSD-3-Clause + +bindto 0.0.0.0 +adapter speed 10000 +reset_config trst_and_srst +adapter srst delay 50 + +adapter driver ftdi +ftdi_vid_pid 0x0403 0x6010 + +ftdi_layout_init 0x0208 0x020b +ftdi_layout_signal nTRST -data 0x0200 -noe 0x0400 +ftdi_layout_signal nSRST -data 0x0100 -noe 0x0800 + diff --git a/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/ft232.cfg b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/ft232.cfg new file mode 100644 index 0000000000..4fb0fba2e7 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/ft232.cfg @@ -0,0 +1,14 @@ +# Copyright 2021 hpmicro +# SPDX-License-Identifier: BSD-3-Clause + +bindto 0.0.0.0 +adapter speed 10000 +reset_config trst_and_srst +adapter srst delay 50 + +adapter driver ftdi +ftdi_vid_pid 0x0403 0x6014 + +ftdi_layout_init 0x0018 0x001b +ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 +ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/jlink.cfg b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/jlink.cfg new file mode 100644 index 0000000000..fd8f04428c --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/jlink.cfg @@ -0,0 +1,11 @@ +# Copyright 2021 hpmicro +# SPDX-License-Identifier: BSD-3-Clause + +bindto 0.0.0.0 +adapter speed 10000 +adapter srst delay 500 + +source [find interface/jlink.cfg] + +transport select jtag +reset_config srst_only diff --git a/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/nds_aice_micro.cfg b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/nds_aice_micro.cfg new file mode 100644 index 0000000000..e9d6e6d698 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/probes/nds_aice_micro.cfg @@ -0,0 +1,14 @@ +# Copyright 2021 hpmicro +# SPDX-License-Identifier: BSD-3-Clause + +bindto 0.0.0.0 +adapter speed 10000 +adapter srst delay 500 +reset_config srst_only + +adapter driver ftdi +ftdi_vid_pid 0x0403 0x6010 + +ftdi_layout_init 0x0008 0x010b +ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 +ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/soc/hpm6e80-dual-core.cfg b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/soc/hpm6e80-dual-core.cfg new file mode 100644 index 0000000000..3776573604 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/soc/hpm6e80-dual-core.cfg @@ -0,0 +1,63 @@ +# Copyright (c) 2024 HPMicro +# SPDX-License-Identifier: BSD-3-Clause +# + + +set _CHIP hpm6e00 +set _CPUTAPID 0x1000563D +jtag newtap $_CHIP cpu -irlen 5 -expected-id $_CPUTAPID + +set _TARGET0 $_CHIP.cpu0 +target create $_TARGET0 riscv -chain-position $_CHIP.cpu -coreid 0 + +$_TARGET0 configure -work-area-phys 0x00000000 -work-area-size 0x20000 -work-area-backup 0 + +targets $_TARGET0 + +proc dmi_write {reg value} { + $::_TARGET0 riscv dmi_write ${reg} ${value} +} + +proc dmi_read {reg} { + set v [$::_TARGET0 riscv dmi_read ${reg}] + return ${v} +} +proc dmi_write_memory {addr value} { + dmi_write 0x39 ${addr} + dmi_write 0x3C ${value} +} + +proc dmi_read_memory {addr} { + set sbcs [expr { 0x100000 | [dmi_read 0x38] }] + dmi_write 0x38 ${sbcs} + dmi_write 0x39 ${addr} + set value [dmi_read 0x3C] + return ${value} +} + +proc release_core1 {} { + dmi_write_memory 0xF4002C00 0x1000 +} + +set _TARGET1 $_CHIP.cpu1 +target create $_TARGET1 riscv -chain-position $_CHIP.cpu -coreid 1 +$_TARGET1 configure -work-area-phys 0x00000000 -work-area-size 0x20000 -work-area-backup 0 + +$_TARGET1 configure -event examine-start { + release_core1 +} + +$_TARGET1 configure -event reset-deassert-pre { + $::_TARGET0 arp_poll + release_core1 +} + +$_TARGET0 configure -event reset-end { + $::_TARGET0 riscv dmi_write 0x39 0xF4002010 + $::_TARGET0 riscv dmi_write 0x3C 0x2 +} + +proc reset_soc {} { + $::_TARGET0 riscv dmi_write 0x39 0xF410001C + $::_TARGET0 riscv dmi_write 0x3C 24000000 +} diff --git a/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/soc/hpm6e80-single-core.cfg b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/soc/hpm6e80-single-core.cfg new file mode 100644 index 0000000000..b80ad2027b --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/debug_scripts/openocd/soc/hpm6e80-single-core.cfg @@ -0,0 +1,18 @@ +# Copyright (c) 2024 HPMicro +# SPDX-License-Identifier: BSD-3-Clause + +set _CHIP hpm6e00 +set _CPUTAPID 0x1000563D +jtag newtap $_CHIP cpu -irlen 5 -expected-id $_CPUTAPID + +set _TARGET0 $_CHIP.cpu0 +target create $_TARGET0 riscv -chain-position $_CHIP.cpu -coreid 0 + +$_TARGET0 configure -work-area-phys 0x00000000 -work-area-size 0x20000 -work-area-backup 0 + +targets $_TARGET0 + +proc reset_soc {} { + $::_TARGET0 riscv dmi_write 0x39 0xF410001C + $::_TARGET0 riscv dmi_write 0x3C 24000000 +} diff --git a/bsp/hpmicro/hpm6e00evk/board/fal_cfg.h b/bsp/hpmicro/hpm6e00evk/board/fal_cfg.h new file mode 100644 index 0000000000..3533c1fbb2 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/fal_cfg.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 hpmicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef _FAL_CFG_H_ +#define _FAL_CFG_H_ + +#include +#include + +#ifdef RT_USING_FAL +#define NOR_FLASH_DEV_NAME "norflash0" +#define NOR_FLASH_MEM_BASE 0x80000000UL +#define NOR_FLASH_SIZE_IN_BYTES 0x1000000UL + +/* ===================== Flash device Configuration ========================= */ +extern const struct fal_flash_dev stm32f2_onchip_flash; +extern struct fal_flash_dev nor_flash0; + +/* flash device table */ +#define FAL_FLASH_DEV_TABLE \ +{ \ + &nor_flash0, \ +} +/* ====================== Partition Configuration ========================== */ +#ifdef FAL_PART_HAS_TABLE_CFG +/* partition table */ +#ifdef CONFIG_WEBNET_FAL_FS +#define FAL_PART_TABLE \ +{ \ + {FAL_PART_MAGIC_WORD, "app", NOR_FLASH_DEV_NAME, 0, 6*1024*1024, 0}, \ + {FAL_PART_MAGIC_WORD, "fs", NOR_FLASH_DEV_NAME, 6*1024*1024, 10*1024*1024, 0}, \ +} +#else +#define FAL_PART_TABLE \ +{ \ + {FAL_PART_MAGIC_WORD, "app", NOR_FLASH_DEV_NAME, 0, 4*1024*1024, 0}, \ + {FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME, 4*1024*1024, 3*1024*1024, 0}, \ + {FAL_PART_MAGIC_WORD, "download", NOR_FLASH_DEV_NAME, 7*1024*1024, 8*1024*1024, 0}, \ + {FAL_PART_MAGIC_WORD, "flashdb", NOR_FLASH_DEV_NAME, 15*1024*1024, 1*1024*1024, 0}, \ +} +#endif +#endif /* FAL_PART_HAS_TABLE_CFG */ +#endif /* RT_USING_FAL */ + +#endif /* _FAL_CFG_H_ */ diff --git a/bsp/hpmicro/hpm6e00evk/board/fal_flash_port.c b/bsp/hpmicro/hpm6e00evk/board/fal_flash_port.c new file mode 100644 index 0000000000..6960ab7f67 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/fal_flash_port.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2022 hpmicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Change Logs: + * Date Author Notes + * 2022-03-09 hpmicro First implementation + * 2022-08-01 hpmicro Fixed random crashing during kvdb_init + * 2022-08-03 hpmicro Improved erase speed + * 2023-05-15 hpmicro Disable global interrupt during FLASH operation for FLASH build + * + */ +#include +#include +#ifdef RT_USING_FAL +#include "fal.h" +#include "hpm_romapi.h" +#include "board.h" +#include "hpm_l1c_drv.h" + +#if defined(FLASH_XIP) && (FLASH_XIP == 1) + +static rt_base_t s_interrupt_level; +#define FAL_ENTER_CRITICAL() do {\ + rt_exit_critical();\ + fencei();\ + s_interrupt_level = rt_hw_interrupt_disable();\ + } while(0) + +#define FAL_EXIT_CRITICAL() do {\ + ROM_API_TABLE_ROOT->xpi_driver_if->software_reset(BOARD_APP_XPI_NOR_XPI_BASE);\ + fencei();\ + rt_exit_critical();\ + rt_hw_interrupt_enable(s_interrupt_level);\ + } while(0) + +#define FAL_RAMFUNC __attribute__((section(".isr_vector"))) + +#else +#define FAL_ENTER_CRITICAL() rt_enter_critical() + +#define FAL_EXIT_CRITICAL() rt_exit_critical() + +#define FAL_RAMFUNC + +#endif + +/*************************************************************************************************** + * FAL Porting Guide + * + * 1. Most FLASH devices do not support RWW (Read-while-Write), the codes to access the FLASH + * must be placed at RAM or ROM code + * 2. During FLASH erase/program, it is recommended to disable the interrupt, or place the + * interrupt related codes to RAM + * + ***************************************************************************************************/ + +static int init(void); +static int read(long offset, uint8_t *buf, size_t size); +static int write(long offset, const uint8_t *buf, size_t size); +static int erase(long offset, size_t size); + +static xpi_nor_config_t s_flashcfg; + +/** + * @brief FAL Flash device context + */ +struct fal_flash_dev nor_flash0 = + { + .name = NOR_FLASH_DEV_NAME, + /* If porting this code to the device with FLASH connected to XPI1, the address must be changed to 0x90000000 */ + .addr = NOR_FLASH_MEM_BASE, + .len = 8 * 1024 * 1024, + .blk_size = 4096, + .ops = { .init = init, .read = read, .write = write, .erase = erase }, + .write_gran = 1 + }; + +/** + * @brief FAL initialization + * This function probes the FLASH using the ROM API + */ +FAL_RAMFUNC static int init(void) +{ + int ret = RT_EOK; + xpi_nor_config_option_t cfg_option; + cfg_option.header.U = BOARD_APP_XPI_NOR_CFG_OPT_HDR; + cfg_option.option0.U = BOARD_APP_XPI_NOR_CFG_OPT_OPT0; + cfg_option.option1.U = BOARD_APP_XPI_NOR_CFG_OPT_OPT1; + + FAL_ENTER_CRITICAL(); + hpm_stat_t status = rom_xpi_nor_auto_config(BOARD_APP_XPI_NOR_XPI_BASE, &s_flashcfg, &cfg_option); + FAL_EXIT_CRITICAL(); + if (status != status_success) + { + ret = -RT_ERROR; + } + else + { + /* update the flash chip information */ + uint32_t sector_size; + rom_xpi_nor_get_property(BOARD_APP_XPI_NOR_XPI_BASE, &s_flashcfg, xpi_nor_property_sector_size, §or_size); + uint32_t flash_size; + rom_xpi_nor_get_property(BOARD_APP_XPI_NOR_XPI_BASE, &s_flashcfg, xpi_nor_property_total_size, &flash_size); + nor_flash0.blk_size = sector_size; + nor_flash0.len = flash_size; + } + + return ret; +} + +/** + * @brief FAL read function + * Read data from FLASH + * @param offset FLASH offset + * @param buf Buffer to hold data read by this API + * @param size Size of data to be read + * @return actual read bytes + */ +FAL_RAMFUNC static int read(long offset, uint8_t *buf, size_t size) +{ + uint32_t flash_addr = nor_flash0.addr + offset; + uint32_t aligned_start = HPM_L1C_CACHELINE_ALIGN_DOWN(flash_addr); + uint32_t aligned_end = HPM_L1C_CACHELINE_ALIGN_UP(flash_addr + size); + uint32_t aligned_size = aligned_end - aligned_start; + rt_base_t level = rt_hw_interrupt_disable(); + l1c_dc_invalidate(aligned_start, aligned_size); + rt_hw_interrupt_enable(level); + + (void) rt_memcpy(buf, (void*) flash_addr, size); + + return size; +} + +/** + * @brief Write unaligned data to the page + * @param offset FLASH offset + * @param buf Data buffer + * @param size Size of data to be written + * @return actual size of written data or error code + */ +FAL_RAMFUNC static int write_unaligned_page_data(long offset, const uint32_t *buf, size_t size) +{ + hpm_stat_t status; + + FAL_ENTER_CRITICAL(); + status = rom_xpi_nor_program(BOARD_APP_XPI_NOR_XPI_BASE, xpi_xfer_channel_auto, &s_flashcfg, buf, offset, size); + FAL_EXIT_CRITICAL(); + + if (status != status_success) + { + return -RT_ERROR; + rt_kprintf("write failed, status=%d\n", status); + } + + return size; +} + +/** + * @brief FAL write function + * Write data to specified FLASH address + * @param offset FLASH offset + * @param buf Data buffer + * @param size Size of data to be written + * @return actual size of written data or error code + */ +FAL_RAMFUNC static int write(long offset, const uint8_t *buf, size_t size) +{ + uint32_t *src = NULL; + uint32_t buf_32[64]; + uint32_t write_size; + size_t remaining_size = size; + int ret = (int)size; + + uint32_t page_size; + rom_xpi_nor_get_property(BOARD_APP_XPI_NOR_XPI_BASE, &s_flashcfg, xpi_nor_property_page_size, &page_size); + uint32_t offset_in_page = offset % page_size; + if (offset_in_page != 0) + { + uint32_t write_size_in_page = page_size - offset_in_page; + uint32_t write_page_size = MIN(write_size_in_page, size); + (void) rt_memcpy(buf_32, buf, write_page_size); + write_size = write_unaligned_page_data(offset, buf_32, write_page_size); + if (write_size < 0) + { + ret = -RT_ERROR; + goto write_quit; + } + + remaining_size -= write_page_size; + offset += write_page_size; + buf += write_page_size; + } + + while (remaining_size > 0) + { + write_size = MIN(remaining_size, sizeof(buf_32)); + rt_memcpy(buf_32, buf, write_size); + src = &buf_32[0]; + + FAL_ENTER_CRITICAL(); + hpm_stat_t status = rom_xpi_nor_program(BOARD_APP_XPI_NOR_XPI_BASE, xpi_xfer_channel_auto, &s_flashcfg, src, + offset, write_size); + FAL_EXIT_CRITICAL(); + + if (status != status_success) + { + ret = -RT_ERROR; + rt_kprintf("write failed, status=%d\n", status); + break; + } + + remaining_size -= write_size; + buf += write_size; + offset += write_size; + } + +write_quit: + return ret; +} + +/** + * @brief FAL erase function + * Erase specified FLASH region + * @param offset the start FLASH address to be erased + * @param size size of the region to be erased + * @ret RT_EOK Erase operation is successful + * @retval -RT_ERROR Erase operation failed + */ +FAL_RAMFUNC static int erase(long offset, size_t size) +{ + uint32_t aligned_size = (size + nor_flash0.blk_size - 1U) & ~(nor_flash0.blk_size - 1U); + hpm_stat_t status; + int ret = (int)size; + + uint32_t block_size; + uint32_t sector_size; + (void) rom_xpi_nor_get_property(BOARD_APP_XPI_NOR_XPI_BASE, &s_flashcfg, xpi_nor_property_sector_size, §or_size); + (void) rom_xpi_nor_get_property(BOARD_APP_XPI_NOR_XPI_BASE, &s_flashcfg, xpi_nor_property_block_size, &block_size); + uint32_t erase_unit; + while (aligned_size > 0) + { + FAL_ENTER_CRITICAL(); + if ((offset % block_size == 0) && (aligned_size >= block_size)) + { + erase_unit = block_size; + status = rom_xpi_nor_erase_block(BOARD_APP_XPI_NOR_XPI_BASE, xpi_xfer_channel_auto, &s_flashcfg, offset); + } + else + { + erase_unit = sector_size; + status = rom_xpi_nor_erase_sector(BOARD_APP_XPI_NOR_XPI_BASE, xpi_xfer_channel_auto, &s_flashcfg, offset); + } + FAL_EXIT_CRITICAL(); + + if (status != status_success) + { + ret = -RT_ERROR; + break; + } + offset += erase_unit; + aligned_size -= erase_unit; + } + + return ret; +} +#endif /* RT_USING_FAL */ diff --git a/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.c b/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.c new file mode 100644 index 0000000000..bbb1b25beb --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.c @@ -0,0 +1,543 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2021 NXP + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include +#include "hpm_wm8960.h" + +#ifndef HPM_WM8960_MCLK_TOLERANCE +#define HPM_WM8960_MCLK_TOLERANCE (4U) +#endif + +/* wm8960 register default value */ +static const uint16_t wm8960_default_reg_val[WM8960_REG_NUM] = { + 0x0097, 0x0097, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x000a, 0x01c0, 0x0000, 0x00ff, 0x00ff, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x007b, 0x0100, 0x0032, 0x0000, 0x00c3, 0x00c3, 0x01c0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0100, 0x0050, 0x0050, 0x0050, 0x0050, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0040, 0x0000, 0x0000, 0x0050, 0x0050, 0x0000, 0x0002, 0x0037, 0x004d, 0x0080, 0x0008, 0x0031, 0x0026, 0x00e9, +}; + +/* store reg value */ +static uint16_t wm8960_reg_val[WM8960_REG_NUM]; + +hpm_stat_t wm8960_init(wm8960_control_t *control, wm8960_config_t *config) +{ + assert(control != NULL); + assert(config != NULL); + + hpm_stat_t stat = status_success; + + (void)memcpy(wm8960_reg_val, wm8960_default_reg_val, sizeof(wm8960_default_reg_val)); + + /* Reset */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RESET, 0x00)); + + /* Power on input modules */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, 0xFE)); + /* Power on output modules */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER2, 0x1F8)); + /* Power on PGA and mixer */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER3, 0x3C)); + + /* ADC and DAC uses same clock */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_IFACE2, 0x40)); + + /* set data protocol */ + HPM_CHECK_RET(wm8960_set_protocol(control, config->bus)); + + /* set wm8960 as slave */ + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_IFACE1, WM8960_IFACE1_MS_MASK, WM8960_IFACE1_MS_SET(0))); + + /* invert LRCLK */ + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_IFACE1, WM8960_IFACE1_LRP_MASK, WM8960_IFACE1_LRP_SET(1))); + + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_ADDCTL1, 0xC0)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_ADDCTL4, 0x40)); + + /* ADC volume, 8dB */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LADC, 0x1D3)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RADC, 0x1D3)); + + /* Digital DAC volume, 0dB */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LDAC, 0x1E0)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RDAC, 0x1E0)); + + /* Headphone volume, LOUT1 and ROUT1, 6dB */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LOUT1, 0x17F)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_ROUT1, 0x17F)); + + /* speaker volume 6dB */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LOUT2, 0x1ff)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_ROUT2, 0x1ff)); + /* enable class D output */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_CLASSD1, 0xf7)); + + /* Unmute DAC. */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_DACCTL1, 0x0000)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINVOL, 0x117)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINVOL, 0x117)); + + HPM_CHECK_RET(wm8960_set_data_format(control, config->format.mclk_hz, config->format.sample_rate, config->format.bit_width)); + + /* set data route */ + HPM_CHECK_RET(wm8960_set_data_route(control, config)); + + return status_success; +} + +hpm_stat_t wm8960_deinit(wm8960_control_t *control) +{ + hpm_stat_t stat = status_success; + + /* power off all modules */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, 0x00U)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER2, 0x00U)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER3, 0x00U)); + + return status_success; +} + +hpm_stat_t wm8960_set_protocol(wm8960_control_t *control, wm8960_protocol_t protocol) +{ + return wm8960_modify_reg(control, WM8960_IFACE1, WM8960_IFACE1_FORMAT_MASK, (uint16_t)protocol); +} + +hpm_stat_t wm8960_set_module(wm8960_control_t *control, wm8960_module_t module, bool enable) +{ + hpm_stat_t stat = status_success; + switch (module) { + case wm8960_module_adc: + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER1, WM8960_POWER1_ADCL_MASK, + ((uint16_t)enable << WM8960_POWER1_ADCL_SHIFT))); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER1, WM8960_POWER1_ADCR_MASK, + ((uint16_t)enable << WM8960_POWER1_ADCR_SHIFT))); + break; + case wm8960_module_dac: + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER2, WM8960_POWER2_DACL_MASK, + ((uint16_t)enable << WM8960_POWER2_DACL_SHIFT))); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER2, WM8960_POWER2_DACR_MASK, + ((uint16_t)enable << WM8960_POWER2_DACR_SHIFT))); + break; + case wm8960_module_vref: + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER1, WM8960_POWER1_VREF_MASK, + ((uint16_t)enable << WM8960_POWER1_VREF_SHIFT))); + break; + case wm8960_module_ana_in: + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER1, WM8960_POWER1_AINL_MASK, + ((uint16_t)enable << WM8960_POWER1_AINL_SHIFT))); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER1, WM8960_POWER1_AINR_MASK, + ((uint16_t)enable << WM8960_POWER1_AINR_SHIFT))); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER3, WM8960_POWER3_LMIC_MASK, + ((uint16_t)enable << WM8960_POWER3_LMIC_SHIFT))); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER3, WM8960_POWER3_RMIC_MASK, + ((uint16_t)enable << WM8960_POWER3_RMIC_SHIFT))); + break; + case wm8960_module_lineout: + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER2, WM8960_POWER2_LOUT1_MASK, + ((uint16_t)enable << WM8960_POWER2_LOUT1_SHIFT))); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER2, WM8960_POWER2_ROUT1_MASK, + ((uint16_t)enable << WM8960_POWER2_ROUT1_SHIFT))); + break; + case wm8960_module_micbais: + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER1, WM8960_POWER1_MICB_MASK, + ((uint16_t)enable << WM8960_POWER1_MICB_SHIFT))); + break; + case wm8960_module_speaker: + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER2, WM8960_POWER2_SPKL_MASK, + ((uint16_t)enable << WM8960_POWER2_SPKL_SHIFT))); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER2, WM8960_POWER2_SPKR_MASK, + ((uint16_t)enable << WM8960_POWER2_SPKR_SHIFT))); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_CLASSD1, 0xF7)); + break; + case wm8960_module_output_mixer: + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER3, WM8960_POWER3_LOMIX_MASK, + ((uint16_t)enable << WM8960_POWER3_LOMIX_SHIFT))); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_POWER3, WM8960_POWER3_ROMIX_MASK, + ((uint16_t)enable << WM8960_POWER3_ROMIX_SHIFT))); + break; + default: + stat = status_invalid_argument; + break; + } + return stat; +} + +hpm_stat_t wm8960_set_data_route(wm8960_control_t *control, wm8960_config_t *config) +{ + hpm_stat_t stat = status_success; + + /* select left input */ + HPM_CHECK_RET(wm8960_set_left_input(control, config->left_input)); + /* select right input */ + HPM_CHECK_RET(wm8960_set_right_input(control, config->right_input)); + /* select source to output mixer */ + HPM_CHECK_RET(wm8960_config_input_to_output_mixer(control, config->play_source)); + + switch (config->route) { + case wm8960_route_bypass: + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_micbais, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_ana_in, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_output_mixer, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_lineout, true)); + break; + case wm8960_route_playback: + /* I2S_IN-> DAC-> HP */ + /* Set power for DAC */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER3, 0x0C)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_dac, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_output_mixer, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_lineout, true)); + break; + case wm8960_route_playback_and_record: + /* Set power */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER3, 0x3C)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_adc, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_micbais, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_ana_in, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_dac, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_output_mixer, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_lineout, true)); + break; + case wm8960_route_record: + /* ANA_IN->ADC->I2S_OUT */ + /* Power up ADC and AIN */ + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER3, 0x30)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_micbais, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_ana_in, true)); + HPM_CHECK_RET(wm8960_set_module(control, wm8960_module_adc, true)); + break; + default: + stat = status_invalid_argument; + break; + } + return stat; +} + +hpm_stat_t wm8960_set_left_input(wm8960_control_t *control, wm8960_input_t input) +{ + hpm_stat_t stat = status_success; + uint16_t val = 0; + + switch (input) { + case wm8960_input_closed: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val &= (uint16_t) ~(WM8960_POWER1_AINL_MASK | WM8960_POWER1_ADCL_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + break; + case wm8960_input_single_ended_mic: + /* Only LMN1 enabled, LMICBOOST to 13db, LMIC2B enabled */ + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINL_MASK | WM8960_POWER1_ADCL_MASK | WM8960_POWER1_MICB_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINPATH, 0x138)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINVOL, 0x117)); + break; + case wm8960_input_differential_mic_input2: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINL_MASK | WM8960_POWER1_ADCL_MASK | WM8960_POWER1_MICB_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINPATH, 0x178)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINVOL, 0x117)); + break; + case wm8960_input_differential_mic_input3: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINL_MASK | WM8960_POWER1_ADCL_MASK | WM8960_POWER1_MICB_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINPATH, 0x1B8)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINVOL, 0x117)); + break; + case wm8960_input_line_input2: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINL_MASK | WM8960_POWER1_ADCL_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_read_reg(WM8960_INBMIX1, &val)); + val |= 0xEU; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_INBMIX1, val)); + break; + case wm8960_input_line_input3: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINL_MASK | WM8960_POWER1_ADCL_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_read_reg(WM8960_INBMIX1, &val)); + val |= 0x70U; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_INBMIX1, val)); + break; + default: + stat = status_invalid_argument; + break; + } + + return stat; +} + +hpm_stat_t wm8960_set_right_input(wm8960_control_t *control, wm8960_input_t input) +{ + hpm_stat_t stat = status_success; + uint16_t val = 0; + + switch (input) { + case wm8960_input_closed: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val &= (uint16_t) ~(WM8960_POWER1_AINR_MASK | WM8960_POWER1_ADCR_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + break; + case wm8960_input_single_ended_mic: + /* Only LMN1 enabled, LMICBOOST to 13db, LMIC2B enabled */ + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINR_MASK | WM8960_POWER1_ADCR_MASK | WM8960_POWER1_MICB_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINPATH, 0x138)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINVOL, 0x117)); + break; + case wm8960_input_differential_mic_input2: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINR_MASK | WM8960_POWER1_ADCR_MASK | WM8960_POWER1_MICB_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINPATH, 0x178)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINVOL, 0x117)); + break; + case wm8960_input_differential_mic_input3: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINR_MASK | WM8960_POWER1_ADCR_MASK | WM8960_POWER1_MICB_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINPATH, 0x1B8)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINVOL, 0x117)); + break; + case wm8960_input_line_input2: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINR_MASK | WM8960_POWER1_ADCR_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_read_reg(WM8960_INBMIX2, &val)); + val |= 0xEU; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_INBMIX2, val)); + break; + case wm8960_input_line_input3: + HPM_CHECK_RET(wm8960_read_reg(WM8960_POWER1, &val)); + val |= (WM8960_POWER1_AINR_MASK | WM8960_POWER1_ADCR_MASK); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_POWER1, val)); + HPM_CHECK_RET(wm8960_read_reg(WM8960_INBMIX2, &val)); + val |= 0x70U; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_INBMIX2, val)); + break; + default: + stat = status_invalid_argument; + break; + } + + return stat; +} + +hpm_stat_t wm8960_set_volume(wm8960_control_t *control, wm8960_module_t module, uint32_t volume) +{ + uint16_t vol = 0; + hpm_stat_t stat = status_success; + switch (module) { + case wm8960_module_adc: + if (volume > 255U) { + stat = status_invalid_argument; + } else { + vol = (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LADC, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RADC, vol)); + /* Update volume */ + vol = (uint16_t)(0x100U | volume); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LADC, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RADC, vol)); + } + break; + case wm8960_module_dac: + if (volume > 255U) { + stat = status_invalid_argument; + } else { + vol = (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LDAC, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RDAC, vol)); + vol = 0x100U | (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LDAC, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RDAC, vol)); + } + break; + case wm8960_module_headphone: + if (volume > 0x7FU) { + stat = status_invalid_argument; + } else { + vol = (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LOUT1, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_ROUT1, vol)); + vol = 0x100U | (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LOUT1, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_ROUT1, vol)); + } + break; + case wm8960_module_ana_in: + if (volume > 0x3FU) { + stat = status_invalid_argument; + } else { + vol = (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINVOL, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINVOL, vol)); + vol = 0x100U | (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LINVOL, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_RINVOL, vol)); + } + break; + case wm8960_module_speaker: + if (volume > 0x7FU) { + stat = status_invalid_argument; + } else { + vol = (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LOUT2, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_ROUT2, vol)); + vol = 0x100U | (uint16_t)volume; + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_LOUT2, vol)); + HPM_CHECK_RET(wm8960_write_reg(control, WM8960_ROUT2, vol)); + } + break; + default: + stat = status_invalid_argument; + break; + } + return stat; +} + +static bool wm8960_check_clock_tolerance(uint32_t source, uint32_t target) +{ + uint32_t delta = (source >= target) ? (source - target) : (target - source); + if (delta * 100 <= HPM_WM8960_MCLK_TOLERANCE * target) { + return true; + } + return false; +} + +hpm_stat_t wm8960_set_data_format(wm8960_control_t *control, uint32_t sysclk, uint32_t sample_rate, uint32_t bits) +{ + hpm_stat_t stat = status_success; + uint16_t val = 0; + uint32_t ratio[7] = {256, 256 * 1.5, 256 * 2, 256 * 3, 256 * 4, 256 * 5.5, 256 * 6}; + bool clock_meet_requirement = false; + + if (sysclk / sample_rate > 256 * 6) { + sysclk = sysclk / 2; + val = WM8960_CLOCK1_SYSCLKDIV_SET(2U); /* SYSCLK Pre-divider */ + } + + for (uint8_t i = 0; i < 7; i++) { + if (wm8960_check_clock_tolerance(sysclk, sample_rate * ratio[i])) { + val |= ((i << WM8960_CLOCK1_ADCDIV_SHIFT) | (i << WM8960_CLOCK1_DACDIV_SHIFT)); + clock_meet_requirement = true; + break; + } + } + + if (!clock_meet_requirement) { + return status_invalid_argument; + } + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_CLOCK1, 0x1FEU, val)); + + /* set sample bit */ + switch (bits) { + case 16: + stat = wm8960_modify_reg(control, WM8960_IFACE1, WM8960_IFACE1_WL_MASK, WM8960_IFACE1_WL_SET(0U)); + break; + case 20: + stat = wm8960_modify_reg(control, WM8960_IFACE1, WM8960_IFACE1_WL_MASK, WM8960_IFACE1_WL_SET(1U)); + break; + case 24: + stat = wm8960_modify_reg(control, WM8960_IFACE1, WM8960_IFACE1_WL_MASK, WM8960_IFACE1_WL_SET(2U)); + break; + case 32: + stat = wm8960_modify_reg(control, WM8960_IFACE1, WM8960_IFACE1_WL_MASK, WM8960_IFACE1_WL_SET(3U)); + break; + default: + stat = status_invalid_argument; + break; + } + + return stat; +} + +hpm_stat_t wm8960_config_input_to_output_mixer(wm8960_control_t *control, uint32_t play_source) +{ + hpm_stat_t stat = status_success; + + if ((play_source & (uint32_t)wm8960_play_source_input_mixer) != 0U) { + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_BYPASS1, 0x80U, 0x80U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_BYPASS2, 0x80U, 0x80U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_LOUTMIX, 0x180U, 0U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_ROUTMIX, 0x180U, 0U)); + } + + if ((play_source & (uint32_t)wm8960_play_source_dac) != 0U) { + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_BYPASS1, 0x80U, 0x00U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_BYPASS2, 0x80U, 0x00U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_LOUTMIX, 0x180U, 0x100U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_ROUTMIX, 0x180U, 0x100U)); + } + + if ((play_source & (uint32_t)wm8960_play_source_input3) != 0U) { + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_BYPASS1, 0x80U, 0x0U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_BYPASS2, 0x80U, 0x0U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_LOUTMIX, 0x180U, 0x80U)); + HPM_CHECK_RET(wm8960_modify_reg(control, WM8960_ROUTMIX, 0x180U, 0x80U)); + } + + return stat; +} + + +hpm_stat_t wm8960_write_reg(wm8960_control_t *control, uint8_t reg, uint16_t val) +{ + /* The first 7 bits (B15 to B9) are address bits that select which control register */ + /* is accessed. The remaining 9 bits (B8 to B0) are data bits */ + rt_size_t size; + rt_uint8_t data[2]; + data[0] = (reg << 1) | (uint8_t)((val >> 8U) & 0x0001U); + data[1] = (uint8_t)(val & 0xFFU); + + size = rt_i2c_master_send(control->i2c_bus, control->slave_address, RT_I2C_WR, data, 2U); + if (size != 2) { + return status_fail; + } + + wm8960_reg_val[reg] = val; + return status_success; +} + +hpm_stat_t wm8960_read_reg(uint8_t reg, uint16_t *val) +{ + if (reg >= WM8960_REG_NUM) { + return status_invalid_argument; + } + *val = wm8960_reg_val[reg]; + + return status_success; +} + +hpm_stat_t wm8960_modify_reg(wm8960_control_t *control, uint8_t reg, uint16_t mask, uint16_t val) +{ + hpm_stat_t stat = 0; + uint16_t reg_val; + + /* Read the register value out */ + stat = wm8960_read_reg(reg, ®_val); + if (stat != status_success) { + return status_fail; + } + + /* Modify the value */ + reg_val &= (uint16_t)~mask; + reg_val |= val; + + /* Write the data to register */ + stat = wm8960_write_reg(control, reg, reg_val); + if (stat != status_success) { + return status_fail; + } + + return status_success; +} diff --git a/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.h b/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.h new file mode 100644 index 0000000000..a288b08db9 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2021 NXP + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef _HPM_WM8960_H_ +#define _HPM_WM8960_H_ + +//#include "hpm_i2c_drv.h" +//#include "hpm_common.h" +#include +#include +#include "rtt_board.h" +#include "drivers/i2c.h" +#include "hpm_wm8960_regs.h" + +#define WM8960_I2C_ADDR 0x1A + +typedef enum wm8960_module { + wm8960_module_adc = 0, /* ADC module in WM8960 */ + wm8960_module_dac = 1, /* DAC module in WM8960 */ + wm8960_module_vref = 2, /* VREF module */ + wm8960_module_headphone = 3, /* Headphone */ + wm8960_module_micbais = 4, /* Mic bias */ + wm8960_module_ana_in = 6, /* Analog in PGA */ + wm8960_module_lineout = 7, /* Line out module */ + wm8960_module_speaker = 8, /* Speaker module */ + wm8960_module_output_mixer = 9, /* Output mixer */ +} wm8960_module_t; + +/* wm8960 play source for output mixer */ +typedef enum wm8960_play_source { + wm8960_play_source_input_mixer = 1, /* Input Boost Mixer to Output Mixer */ + wm8960_play_source_input3 = 2, /* L/RINPUT3 to Output Mixer */ + wm8960_play_source_dac = 4, /* DAC to Output Mixer */ +} wm8960_play_source_t; + +/* WM8960 data route */ +typedef enum wm8960_route { + wm8960_route_bypass = 0, /* ANA_IN->Headphone. */ + wm8960_route_playback = 1, /* I2SIN->DAC->Headphone. */ + wm8960_route_playback_and_record = 2, /* I2SIN->DAC->Headphone, ANA_IN->ADC->I2SOUT. */ + wm8960_route_record = 5 /* ANA_IN->ADC->I2SOUT. */ +} wm8960_route_t; + +/* The audio data transfer protocol choice */ +typedef enum wm8960_protocol { + wm8960_bus_i2s = 2, /* I2S type */ + wm8960_bus_left_justified = 1, /* Left justified mode */ + wm8960_bus_right_justified = 0, /* Right justified mode */ + wm8960_bus_pcma = 3, /* PCM A mode */ + wm8960_bus_pcmb = 3 | (1 << 4) /* PCM B mode */ +} wm8960_protocol_t; + +/* wm8960 input source */ +typedef enum wm8960_input { + wm8960_input_closed = 0, /* Input device is closed */ + wm8960_input_single_ended_mic = 1, /* Input as single ended mic, only use L/RINPUT1 */ + wm8960_input_differential_mic_input2 = 2, /* Input as differential mic, use L/RINPUT1 and L/RINPUT2 */ + wm8960_input_differential_mic_input3 = 3, /* Input as differential mic, use L/RINPUT1 and L/RINPUT3*/ + wm8960_input_line_input2 = 4, /* Input as line input, only use L/RINPUT2 */ + wm8960_input_line_input3 = 5 /* Input as line input, only use L/RINPUT3 */ +} wm8960_input_t; + +/* wm8960 audio format */ +typedef struct wm8960_audio_format { + uint32_t mclk_hz; /* master clock frequency */ + uint32_t sample_rate; /* sample rate */ + uint32_t bit_width; /* bit width */ +} wm8960_audio_format_t; + +/* configure structure of WM8960 */ +typedef struct wm8960_config { + wm8960_route_t route; /* Audio data route.*/ + wm8960_protocol_t bus; /* Audio transfer protocol */ + bool enable_speaker; /* True means enable class D speaker as output, false means no */ + wm8960_input_t left_input; /* Left input source for WM8960 */ + wm8960_input_t right_input; /* Right input source for wm8960 */ + wm8960_play_source_t play_source; /* play source */ + wm8960_audio_format_t format; /* Audio format */ +} wm8960_config_t; + +typedef struct { + struct rt_i2c_bus_device *i2c_bus; /* I2C bus device */ + uint8_t slave_address; /* code device address */ +} wm8960_control_t; + + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @brief WM8960 initialize function. + * + * @param control WM8960 control structure. + * @param config WM8960 configuration structure. + */ +hpm_stat_t wm8960_init(wm8960_control_t *control, wm8960_config_t *config); + +/** + * @brief Deinit the WM8960 codec. + * + * This function close all modules in WM8960 to save power. + * + * @param control WM8960 control structure pointer. + */ +hpm_stat_t wm8960_deinit(wm8960_control_t *control); + +/** + * @brief Set audio data route in WM8960. + * + * This function would set the data route according to route. + * + * @param control WM8960 control structure. + * @param config Audio configure structure in WM8960. + */ +hpm_stat_t wm8960_set_data_route(wm8960_control_t *control, wm8960_config_t *config); + +/** + * @brief Set left audio input source in WM8960. + * + * @param control WM8960 control structure. + * @param input Audio input source. + */ +hpm_stat_t wm8960_set_left_input(wm8960_control_t *control, wm8960_input_t input); + +/** + * @brief Set right audio input source in WM8960. + * + * @param control WM8960 control structure. + * @param input Audio input source. + */ +hpm_stat_t wm8960_set_right_input(wm8960_control_t *control, wm8960_input_t input); + +/** + * @brief Set the audio transfer protocol. + * + * @param control WM8960 control structure. + * @param protocol Audio data transfer protocol. + */ +hpm_stat_t wm8960_set_protocol(wm8960_control_t *control, wm8960_protocol_t protocol); + +/** + * @brief Set the volume of different modules in WM8960. + * + * This function would set the volume of WM8960 modules. Uses need to appoint the module. + * The function assume that left channel and right channel has the same volume. + * + * Module:wm8960_module_adc, volume range value: 0 is mute, 1-255 is -97db to 30db + * Module:wm8960_module_dac, volume range value: 0 is mute, 1-255 is -127db to 0db + * Module:wm8960_module_headphone, volume range value: 0 - 2F is mute, 0x30 - 0x7F is -73db to 6db + * Module:wm8960_module_ana_in, volume range value: 0 - 0x3F is -17.25db to 30db + * Module:wm8960_module_speaker, volume range value: 0 - 2F is mute, 0x30 - 0x7F is -73db to 6db + * + * + * @param control WM8960 control structure. + * @param module Module to set volume, it can be ADC, DAC, Headphone and so on. + * @param volume Volume value need to be set. + */ +hpm_stat_t wm8960_set_volume(wm8960_control_t *control, wm8960_module_t module, uint32_t volume); + +/** + * @brief Enable/disable expected module. + * + * @param control WM8960 control structure. + * @param module Module expected to enable. + * @param enable Enable or disable moudles. + */ +hpm_stat_t wm8960_set_module(wm8960_control_t *control, wm8960_module_t module, bool enable); + +/** + * @brief SET the WM8960 play source. + * + * @param control WM8960 control structure. + * @param play_source play source + * + * @return kStatus_WM8904_Success if successful, different code otherwise.. + */ +hpm_stat_t wm8960_config_input_to_output_mixer(wm8960_control_t *control, uint32_t play_source); + +/** + * @brief Configure the data format of audio data. + * + * This function would configure the registers about the sample rate, bit depths. + * + * @param control WM8960 control structure pointer. + * @param sysclk system clock of the codec which can be generated by MCLK or PLL output. + * @param sample_rate Sample rate of audio file running in WM8960. WM8960 now + * supports 8k, 11.025k, 12k, 16k, 22.05k, 24k, 32k, 44.1k, 48k and 96k sample rate. + * @param bits Bit depth of audio file (WM8960 only supports 16bit, 20bit, 24bit + * and 32 bit in HW). + */ +hpm_stat_t wm8960_set_data_format(wm8960_control_t *control, uint32_t sysclk, uint32_t sample_rate, uint32_t bits); + + +/** + * @brief Write register to WM8960 using I2C. + * + * @param control WM8960 control structure. + * @param reg The register address in WM8960. + * @param val Value needs to write into the register. + */ +hpm_stat_t wm8960_write_reg(wm8960_control_t *control, uint8_t reg, uint16_t val); + +/** + * @brief Read register from WM8960 using I2C. + * @param reg The register address in WM8960. + * @param val Value written to. + */ +hpm_stat_t wm8960_read_reg(uint8_t reg, uint16_t *val); + +/** + * @brief Modify some bits in the register using I2C. + * @param control WM8960 control structure. + * @param reg The register address in WM8960. + * @param mask The mask code for the bits want to write. The bit you want to write should be 0. + * @param val Value needs to write into the register. + */ +hpm_stat_t wm8960_modify_reg(wm8960_control_t *control, uint8_t reg, uint16_t mask, uint16_t val); + + +#endif /* _HPM_WM8960_H_ */ diff --git a/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960_regs.h b/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960_regs.h new file mode 100644 index 0000000000..a484f2937c --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/hpm_wm8960_regs.h @@ -0,0 +1,2139 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef _HPM_WM8960_REG_H_ +#define _HPM_WM8960_REG_H_ + +/* WM8960 register number */ +#define WM8960_REG_NUM 56U + +/* Define the register address of WM8960 */ +#define WM8960_LINVOL 0x0U /* Left Input Volume */ +#define WM8960_RINVOL 0x1U /* Right Input Volume */ +#define WM8960_LOUT1 0x2U /* LOUT1 Volume */ +#define WM8960_ROUT1 0x3U /* ROUT1 Volume */ +#define WM8960_CLOCK1 0x4U /* Clocking(1) */ +#define WM8960_DACCTL1 0x5U /* ADC and DAC Control (1) */ +#define WM8960_DACCTL2 0x6U /* ADC and DAC Control (2) */ +#define WM8960_IFACE1 0x7U /* Audio Interface */ +#define WM8960_CLOCK2 0x8U /* Clocking(2) */ +#define WM8960_IFACE2 0x9U /* Audio Interface */ +#define WM8960_LDAC 0xaU /* Left DAC */ +#define WM8960_RDAC 0xbU /* Right DAC Volume */ +#define WM8960_RESET 0xfU /* RESET */ +#define WM8960_3D 0x10U /* 3D Control */ +#define WM8960_ALC1 0x11U /* ALC (1) */ +#define WM8960_ALC2 0x12U /* ALC (2) */ +#define WM8960_ALC3 0x13U /* ALC (3) */ +#define WM8960_NOISEG 0x14U /* Noise Gate */ +#define WM8960_LADC 0x15U /* Left ADC Volume */ +#define WM8960_RADC 0x16U /* Right ADC Volume */ +#define WM8960_ADDCTL1 0x17U /* Additional Control (1) */ +#define WM8960_ADDCTL2 0x18U /* Additional Control (2) */ +#define WM8960_POWER1 0x19U /* Power Mgmt (1) */ +#define WM8960_POWER2 0x1aU /* Power Mgmt (2) */ +#define WM8960_ADDCTL3 0x1bU /* Additional Control (3) */ +#define WM8960_APOP1 0x1cU /* Anti-Pop 1 */ +#define WM8960_APOP2 0x1dU /* Anti-pop 2 */ +#define WM8960_LINPATH 0x20U /* ADCL Signal Path */ +#define WM8960_RINPATH 0x21U /* ADCR Signal Path */ +#define WM8960_LOUTMIX 0x22U /* Left Out Mix */ +#define WM8960_ROUTMIX 0x25U /* Right Out Mix */ +#define WM8960_MONOMIX1 0x26U /* Mono Out Mix (1) */ +#define WM8960_MONOMIX2 0x27U /* Mono Out Mix (2) */ +#define WM8960_LOUT2 0x28U /* Left Speaker Volume */ +#define WM8960_ROUT2 0x29U /* Right Speaker Volume */ +#define WM8960_MONO 0x2aU /* OUT3 Volume */ +#define WM8960_INBMIX1 0x2bU /* Left Input Boost Mixer */ +#define WM8960_INBMIX2 0x2cU /* Right Input Boost Mixer */ +#define WM8960_BYPASS1 0x2dU /* Left Bypass */ +#define WM8960_BYPASS2 0x2eU /* Right Bypass */ +#define WM8960_POWER3 0x2fU /* Power Mgmt (3) */ +#define WM8960_ADDCTL4 0x30U /* Additional Control (4) */ +#define WM8960_CLASSD1 0x31U /* Class D Control (1) */ +#define WM8960_CLASSD3 0x33U /* Class D Control (2) */ +#define WM8960_PLL1 0x34U /* PLL (1) */ +#define WM8960_PLL2 0x35U /* PLL (2) */ +#define WM8960_PLL3 0x36U /* PLL (3) */ +#define WM8960_PLL4 0x37U /* PLL (4) */ + +/* Bitfield definition for register: LINVO */ +/* + * IPVU (RW) + * + * Input PGA Volume Update + * Writing a 1 to this bit will cause left and right input PGA volumes to be updated (LINVOL and RINVOL) + */ +#define WM8960_LINVO_IPVU_MASK (0x100U) +#define WM8960_LINVO_IPVU_SHIFT (8U) +#define WM8960_LINVO_IPVU_SET(x) (((uint16_t)(x) << WM8960_LINVO_IPVU_SHIFT) & WM8960_LINVO_IPVU_MASK) +#define WM8960_LINVO_IPVU_GET(x) (((uint16_t)(x) & WM8960_LINVO_IPVU_MASK) >> WM8960_LINVO_IPVU_SHIFT) + +/* + * LINMUTE (RW) + * + * Left Input PGA Analogue Mute 1 = Enable Mute 0 = Disable Mute Note: IPVU must be set to un-mute. + */ +#define WM8960_LINVO_LINMUTE_MASK (0x80U) +#define WM8960_LINVO_LINMUTE_SHIFT (7U) +#define WM8960_LINVO_LINMUTE_SET(x) (((uint16_t)(x) << WM8960_LINVO_LINMUTE_SHIFT) & WM8960_LINVO_LINMUTE_MASK) +#define WM8960_LINVO_LINMUTE_GET(x) (((uint16_t)(x) & WM8960_LINVO_LINMUTE_MASK) >> WM8960_LINVO_LINMUTE_SHIFT) + +/* + * LIZC (RW) + * + * Left Input PGA Zero Cross Detector 1 = Change gain on zero cross only 0 = Change gain immediately + */ +#define WM8960_LINVO_LIZC_MASK (0x40U) +#define WM8960_LINVO_LIZC_SHIFT (6U) +#define WM8960_LINVO_LIZC_SET(x) (((uint16_t)(x) << WM8960_LINVO_LIZC_SHIFT) & WM8960_LINVO_LIZC_MASK) +#define WM8960_LINVO_LIZC_GET(x) (((uint16_t)(x) & WM8960_LINVO_LIZC_MASK) >> WM8960_LINVO_LIZC_SHIFT) + +/* + * LINVOL (RW) + * + * Left Input PGA Volume Control + * 111111 = +30dB + * 111110 = +29.25dB + * . . 0.75dB steps down to + * 000000 = -17.25dB + */ +#define WM8960_LINVO_LINVOL_MASK (0x3FU) +#define WM8960_LINVO_LINVOL_SHIFT (0U) +#define WM8960_LINVO_LINVOL_SET(x) (((uint16_t)(x) << WM8960_LINVO_LINVOL_SHIFT) & WM8960_LINVO_LINVOL_MASK) +#define WM8960_LINVO_LINVOL_GET(x) (((uint16_t)(x) & WM8960_LINVO_LINVOL_MASK) >> WM8960_LINVO_LINVOL_SHIFT) + +/* Bitfield definition for register: RINVOL */ +/* + * IPVU (RW) + * + * Input PGA Volume Update + * Writing a 1 to this bit will cause left and right + * input PGA volumes to be updated (LINVOL and RINVOL) + */ +#define WM8960_RINVOL_IPVU_MASK (0x100U) +#define WM8960_RINVOL_IPVU_SHIFT (8U) +#define WM8960_RINVOL_IPVU_SET(x) (((uint16_t)(x) << WM8960_RINVOL_IPVU_SHIFT) & WM8960_RINVOL_IPVU_MASK) +#define WM8960_RINVOL_IPVU_GET(x) (((uint16_t)(x) & WM8960_RINVOL_IPVU_MASK) >> WM8960_RINVOL_IPVU_SHIFT) + +/* + * RINMUTE (RW) + * + * Right Input PGA Analogue Mute + * 1 = Enable Mute + * 0 = Disable Mute + * Note: IPVU must be set to un-mute. + */ +#define WM8960_RINVOL_RINMUTE_MASK (0x80U) +#define WM8960_RINVOL_RINMUTE_SHIFT (7U) +#define WM8960_RINVOL_RINMUTE_SET(x) (((uint16_t)(x) << WM8960_RINVOL_RINMUTE_SHIFT) & WM8960_RINVOL_RINMUTE_MASK) +#define WM8960_RINVOL_RINMUTE_GET(x) (((uint16_t)(x) & WM8960_RINVOL_RINMUTE_MASK) >> WM8960_RINVOL_RINMUTE_SHIFT) + +/* + * RIZC (RW) + * + * Right Input PGA Zero Cross Detector + * 1 = Change gain on zero cross only + * 0 = Change gain immediately + */ +#define WM8960_RINVOL_RIZC_MASK (0x40U) +#define WM8960_RINVOL_RIZC_SHIFT (6U) +#define WM8960_RINVOL_RIZC_SET(x) (((uint16_t)(x) << WM8960_RINVOL_RIZC_SHIFT) & WM8960_RINVOL_RIZC_MASK) +#define WM8960_RINVOL_RIZC_GET(x) (((uint16_t)(x) & WM8960_RINVOL_RIZC_MASK) >> WM8960_RINVOL_RIZC_SHIFT) + +/* + * RINVOL (RW) + * + * Right Input PGA Volume Control + * 111111 = +30dB + * 111110 = +29.25dB + * . . 0.75dB steps down to + * 000000 = -17.25dB + */ +#define WM8960_RINVOL_RINVOL_MASK (0x3FU) +#define WM8960_RINVOL_RINVOL_SHIFT (0U) +#define WM8960_RINVOL_RINVOL_SET(x) (((uint16_t)(x) << WM8960_RINVOL_RINVOL_SHIFT) & WM8960_RINVOL_RINVOL_MASK) +#define WM8960_RINVOL_RINVOL_GET(x) (((uint16_t)(x) & WM8960_RINVOL_RINVOL_MASK) >> WM8960_RINVOL_RINVOL_SHIFT) + +/* Bitfield definition for register: LOUT1 */ +/* + * OUT1VU (RW) + * + * Headphone Output PGA Volume Update + * Writing a 1 to this bit will cause left and right + * headphone output volumes to be updated + * (LOUT1VOL and ROUT1VOL) + */ +#define WM8960_LOUT1_OUT1VU_MASK (0x100U) +#define WM8960_LOUT1_OUT1VU_SHIFT (8U) +#define WM8960_LOUT1_OUT1VU_SET(x) (((uint16_t)(x) << WM8960_LOUT1_OUT1VU_SHIFT) & WM8960_LOUT1_OUT1VU_MASK) +#define WM8960_LOUT1_OUT1VU_GET(x) (((uint16_t)(x) & WM8960_LOUT1_OUT1VU_MASK) >> WM8960_LOUT1_OUT1VU_SHIFT) + +/* + * LO1ZC (RW) + * + * Left Headphone Output Zero Cross Enable + * 0 = Change gain immediately + * 1 = Change gain on zero cross only + */ +#define WM8960_LOUT1_LO1ZC_MASK (0x80U) +#define WM8960_LOUT1_LO1ZC_SHIFT (7U) +#define WM8960_LOUT1_LO1ZC_SET(x) (((uint16_t)(x) << WM8960_LOUT1_LO1ZC_SHIFT) & WM8960_LOUT1_LO1ZC_MASK) +#define WM8960_LOUT1_LO1ZC_GET(x) (((uint16_t)(x) & WM8960_LOUT1_LO1ZC_MASK) >> WM8960_LOUT1_LO1ZC_SHIFT) + +/* + * LOUT1VOL (RW) + * + * LOUT1 Volume + * 1111111 = +6dB + * … 1dB steps down to + * 0110000 = -73dB + * 0101111 to 0000000 = Analogue MUTE + */ +#define WM8960_LOUT1_LOUT1VOL_MASK (0x7FU) +#define WM8960_LOUT1_LOUT1VOL_SHIFT (0U) +#define WM8960_LOUT1_LOUT1VOL_SET(x) (((uint16_t)(x) << WM8960_LOUT1_LOUT1VOL_SHIFT) & WM8960_LOUT1_LOUT1VOL_MASK) +#define WM8960_LOUT1_LOUT1VOL_GET(x) (((uint16_t)(x) & WM8960_LOUT1_LOUT1VOL_MASK) >> WM8960_LOUT1_LOUT1VOL_SHIFT) + +/* Bitfield definition for register: ROUT1 */ +/* + * OUT1VU (RW) + * + * Headphone Output PGA Volume Update + * Writing a 1 to this bit will cause left and right + * headphone output volumes to be updated + * (LOUT1VOL and ROUT1VOL) + */ +#define WM8960_ROUT1_OUT1VU_MASK (0x100U) +#define WM8960_ROUT1_OUT1VU_SHIFT (8U) +#define WM8960_ROUT1_OUT1VU_SET(x) (((uint16_t)(x) << WM8960_ROUT1_OUT1VU_SHIFT) & WM8960_ROUT1_OUT1VU_MASK) +#define WM8960_ROUT1_OUT1VU_GET(x) (((uint16_t)(x) & WM8960_ROUT1_OUT1VU_MASK) >> WM8960_ROUT1_OUT1VU_SHIFT) + +/* + * RO1ZC (RW) + * + * Right Headphone Output Zero Cross Enable + * 0 = Change gain immediately + * 1 = Change gain on zero cross only + */ +#define WM8960_ROUT1_RO1ZC_MASK (0x80U) +#define WM8960_ROUT1_RO1ZC_SHIFT (7U) +#define WM8960_ROUT1_RO1ZC_SET(x) (((uint16_t)(x) << WM8960_ROUT1_RO1ZC_SHIFT) & WM8960_ROUT1_RO1ZC_MASK) +#define WM8960_ROUT1_RO1ZC_GET(x) (((uint16_t)(x) & WM8960_ROUT1_RO1ZC_MASK) >> WM8960_ROUT1_RO1ZC_SHIFT) + +/* + * ROUT1VOL (RW) + * + * ROUT1 Volume + * 1111111 = +6dB + * … 1dB steps down to + * 0110000 = -73dB + * 0101111 to 0000000 = Analogue MUTE + */ +#define WM8960_ROUT1_ROUT1VOL_MASK (0x7FU) +#define WM8960_ROUT1_ROUT1VOL_SHIFT (0U) +#define WM8960_ROUT1_ROUT1VOL_SET(x) (((uint16_t)(x) << WM8960_ROUT1_ROUT1VOL_SHIFT) & WM8960_ROUT1_ROUT1VOL_MASK) +#define WM8960_ROUT1_ROUT1VOL_GET(x) (((uint16_t)(x) & WM8960_ROUT1_ROUT1VOL_MASK) >> WM8960_ROUT1_ROUT1VOL_SHIFT) + +/* Bitfield definition for register: CLOCK1 */ +/* + * ADCDIV (RW) + * + * ADC Sample rate divider (Also determines + * ADCLRC in master mode) + * 000 = SYSCLK / (1.0 * 256) + * 001 = SYSCLK / (1.5 * 256) + * 010 = SYSCLK / (2 * 256) + * 011 = SYSCLK / (3 * 256) + * 100 = SYSCLK / (4 * 256) + * 101 = SYSCLK / (5.5 * 256) + * 110 = SYSCLK / (6 * 256) + * 111 = Reserved + */ +#define WM8960_CLOCK1_ADCDIV_MASK (0x1C0U) +#define WM8960_CLOCK1_ADCDIV_SHIFT (6U) +#define WM8960_CLOCK1_ADCDIV_SET(x) (((uint16_t)(x) << WM8960_CLOCK1_ADCDIV_SHIFT) & WM8960_CLOCK1_ADCDIV_MASK) +#define WM8960_CLOCK1_ADCDIV_GET(x) (((uint16_t)(x) & WM8960_CLOCK1_ADCDIV_MASK) >> WM8960_CLOCK1_ADCDIV_SHIFT) + +/* + * DACDIV (RW) + * + * DAC Sample rate divider (Also determines + * DACLRC in master mode) + * 000 = SYSCLK / (1.0 * 256) + * 001 = SYSCLK / (1.5 * 256) + * 010 = SYSCLK / (2 * 256) + * 011 = SYSCLK / (3 * 256) + * 100 = SYSCLK / (4 * 256) + * 101 = SYSCLK / (5.5 * 256) + * 110 = SYSCLK / (6 * 256) + * 111 = Reserved + */ +#define WM8960_CLOCK1_DACDIV_MASK (0x38U) +#define WM8960_CLOCK1_DACDIV_SHIFT (3U) +#define WM8960_CLOCK1_DACDIV_SET(x) (((uint16_t)(x) << WM8960_CLOCK1_DACDIV_SHIFT) & WM8960_CLOCK1_DACDIV_MASK) +#define WM8960_CLOCK1_DACDIV_GET(x) (((uint16_t)(x) & WM8960_CLOCK1_DACDIV_MASK) >> WM8960_CLOCK1_DACDIV_SHIFT) + +/* + * SYSCLKDIV (RW) + * + * SYSCLK Pre-divider. Clock source (MCLK or + * PLL output) will be divided by this value to + * generate SYSCLK. + * 00 = Divide SYSCLK by 1 + * 01 = Reserved + * 10 = Divide SYSCLK by 2 + * 11 = Reserved + */ +#define WM8960_CLOCK1_SYSCLKDIV_MASK (0x6U) +#define WM8960_CLOCK1_SYSCLKDIV_SHIFT (1U) +#define WM8960_CLOCK1_SYSCLKDIV_SET(x) (((uint16_t)(x) << WM8960_CLOCK1_SYSCLKDIV_SHIFT) & WM8960_CLOCK1_SYSCLKDIV_MASK) +#define WM8960_CLOCK1_SYSCLKDIV_GET(x) (((uint16_t)(x) & WM8960_CLOCK1_SYSCLKDIV_MASK) >> WM8960_CLOCK1_SYSCLKDIV_SHIFT) + +/* + * CLKSEL (RW) + * + * SYSCLK Selection + * 0 = SYSCLK derived from MCLK + * 1 = SYSCLK derived from PLL output + */ +#define WM8960_CLOCK1_CLKSEL_MASK (0x1U) +#define WM8960_CLOCK1_CLKSEL_SHIFT (0U) +#define WM8960_CLOCK1_CLKSEL_SET(x) (((uint16_t)(x) << WM8960_CLOCK1_CLKSEL_SHIFT) & WM8960_CLOCK1_CLKSEL_MASK) +#define WM8960_CLOCK1_CLKSEL_GET(x) (((uint16_t)(x) & WM8960_CLOCK1_CLKSEL_MASK) >> WM8960_CLOCK1_CLKSEL_SHIFT) + +/* Bitfield definition for register: DACCTL1 */ +/* + * DACDIV2 (RW) + * + * DAC 6dB Attenuate Enable + * 0 = Disabled (0dB) + * 1 = -6dB Enabled + */ +#define WM8960_DACCTL1_DACDIV2_MASK (0x80U) +#define WM8960_DACCTL1_DACDIV2_SHIFT (7U) +#define WM8960_DACCTL1_DACDIV2_SET(x) (((uint16_t)(x) << WM8960_DACCTL1_DACDIV2_SHIFT) & WM8960_DACCTL1_DACDIV2_MASK) +#define WM8960_DACCTL1_DACDIV2_GET(x) (((uint16_t)(x) & WM8960_DACCTL1_DACDIV2_MASK) >> WM8960_DACCTL1_DACDIV2_SHIFT) + +/* + * ADCPOL (RW) + * + * ADC polarity control: + * 00 = Polarity not inverted + * 01 = ADC L inverted + * 10 = ADC R inverted + * 11 = ADC L and R inverted + */ +#define WM8960_DACCTL1_ADCPOL_MASK (0x60U) +#define WM8960_DACCTL1_ADCPOL_SHIFT (5U) +#define WM8960_DACCTL1_ADCPOL_SET(x) (((uint16_t)(x) << WM8960_DACCTL1_ADCPOL_SHIFT) & WM8960_DACCTL1_ADCPOL_MASK) +#define WM8960_DACCTL1_ADCPOL_GET(x) (((uint16_t)(x) & WM8960_DACCTL1_ADCPOL_MASK) >> WM8960_DACCTL1_ADCPOL_SHIFT) + +/* + * DACMU (RW) + * + * DAC Digital Soft Mute + * 1 = Mute + * 0 = No mute (signal active) + */ +#define WM8960_DACCTL1_DACMU_MASK (0x8U) +#define WM8960_DACCTL1_DACMU_SHIFT (3U) +#define WM8960_DACCTL1_DACMU_SET(x) (((uint16_t)(x) << WM8960_DACCTL1_DACMU_SHIFT) & WM8960_DACCTL1_DACMU_MASK) +#define WM8960_DACCTL1_DACMU_GET(x) (((uint16_t)(x) & WM8960_DACCTL1_DACMU_MASK) >> WM8960_DACCTL1_DACMU_SHIFT) + +/* + * DEEMPH (RW) + * + * De-emphasis Control + * 11 = 48kHz sample rate + * 10 = 44.1kHz sample rate + * 01 = 32kHz sample rate + * 00 = No de-emphasis + */ +#define WM8960_DACCTL1_DEEMPH_MASK (0x6U) +#define WM8960_DACCTL1_DEEMPH_SHIFT (1U) +#define WM8960_DACCTL1_DEEMPH_SET(x) (((uint16_t)(x) << WM8960_DACCTL1_DEEMPH_SHIFT) & WM8960_DACCTL1_DEEMPH_MASK) +#define WM8960_DACCTL1_DEEMPH_GET(x) (((uint16_t)(x) & WM8960_DACCTL1_DEEMPH_MASK) >> WM8960_DACCTL1_DEEMPH_SHIFT) + +/* + * ADCHPD (RW) + * + * ADC High Pass Filter Disable + * 0 = Enable high pass filter on left and right channels + * 1 = Disable high pass filter on left and right channels + */ +#define WM8960_DACCTL1_ADCHPD_MASK (0x1U) +#define WM8960_DACCTL1_ADCHPD_SHIFT (0U) +#define WM8960_DACCTL1_ADCHPD_SET(x) (((uint16_t)(x) << WM8960_DACCTL1_ADCHPD_SHIFT) & WM8960_DACCTL1_ADCHPD_MASK) +#define WM8960_DACCTL1_ADCHPD_GET(x) (((uint16_t)(x) & WM8960_DACCTL1_ADCHPD_MASK) >> WM8960_DACCTL1_ADCHPD_SHIFT) + +/* Bitfield definition for register: DACCTL2 */ +/* + * DACPOL (RW) + * + * DAC polarity control: + * 00 = Polarity not inverted + * 01 = DAC L inverted + * 10 = DAC R inverted + * 11 = DAC L and R inverted + */ +#define WM8960_DACCTL2_DACPOL_MASK (0x60U) +#define WM8960_DACCTL2_DACPOL_SHIFT (5U) +#define WM8960_DACCTL2_DACPOL_SET(x) (((uint16_t)(x) << WM8960_DACCTL2_DACPOL_SHIFT) & WM8960_DACCTL2_DACPOL_MASK) +#define WM8960_DACCTL2_DACPOL_GET(x) (((uint16_t)(x) & WM8960_DACCTL2_DACPOL_MASK) >> WM8960_DACCTL2_DACPOL_SHIFT) + +/* + * DACSMM (RW) + * + * DAC Soft Mute Mode + * 0 = Disabling soft-mute (DACMU=0) will cause + * the volume to change immediately to the + * LDACVOL / RDACVOL settings + * 1 = Disabling soft-mute (DACMU=0) will cause + * the volume to ramp up gradually to the + * LDACVOL / RDACVOL settings + */ +#define WM8960_DACCTL2_DACSMM_MASK (0x8U) +#define WM8960_DACCTL2_DACSMM_SHIFT (3U) +#define WM8960_DACCTL2_DACSMM_SET(x) (((uint16_t)(x) << WM8960_DACCTL2_DACSMM_SHIFT) & WM8960_DACCTL2_DACSMM_MASK) +#define WM8960_DACCTL2_DACSMM_GET(x) (((uint16_t)(x) & WM8960_DACCTL2_DACSMM_MASK) >> WM8960_DACCTL2_DACSMM_SHIFT) + +/* + * DACMR (RW) + * + * DAC Soft Mute Ramp Rate + * 0 = Fast ramp (24kHz at fs=48k, providing + * maximum delay of 10.7ms) + * 1 = Slow ramp (1.5kHz at fs=48k, providing + * maximum delay of 171ms) + */ +#define WM8960_DACCTL2_DACMR_MASK (0x4U) +#define WM8960_DACCTL2_DACMR_SHIFT (2U) +#define WM8960_DACCTL2_DACMR_SET(x) (((uint16_t)(x) << WM8960_DACCTL2_DACMR_SHIFT) & WM8960_DACCTL2_DACMR_MASK) +#define WM8960_DACCTL2_DACMR_GET(x) (((uint16_t)(x) & WM8960_DACCTL2_DACMR_MASK) >> WM8960_DACCTL2_DACMR_SHIFT) + +/* + * DACSLOPE (RW) + * + * Selects DAC filter characteristics + * 0 = Normal mode + * 1 = Sloping stopband + */ +#define WM8960_DACCTL2_DACSLOPE_MASK (0x2U) +#define WM8960_DACCTL2_DACSLOPE_SHIFT (1U) +#define WM8960_DACCTL2_DACSLOPE_SET(x) (((uint16_t)(x) << WM8960_DACCTL2_DACSLOPE_SHIFT) & WM8960_DACCTL2_DACSLOPE_MASK) +#define WM8960_DACCTL2_DACSLOPE_GET(x) (((uint16_t)(x) & WM8960_DACCTL2_DACSLOPE_MASK) >> WM8960_DACCTL2_DACSLOPE_SHIFT) + +/* Bitfield definition for register: IFACE1 */ +/* + * ALRSWAP (RW) + * + * Left/Right ADC Channel Swap + * 1 = Swap left and right ADC data in audio + * interface + * 0 = Output left and right data as normal + */ +#define WM8960_IFACE1_ALRSWAP_MASK (0x100U) +#define WM8960_IFACE1_ALRSWAP_SHIFT (8U) +#define WM8960_IFACE1_ALRSWAP_SET(x) (((uint16_t)(x) << WM8960_IFACE1_ALRSWAP_SHIFT) & WM8960_IFACE1_ALRSWAP_MASK) +#define WM8960_IFACE1_ALRSWAP_GET(x) (((uint16_t)(x) & WM8960_IFACE1_ALRSWAP_MASK) >> WM8960_IFACE1_ALRSWAP_SHIFT) + +/* + * BCLKINV (RW) + * + * BCLK invert bit (for master and slave modes) + * 0 = BCLK not inverted + * 1 = BCLK inverted + */ +#define WM8960_IFACE1_BCLKINV_MASK (0x80U) +#define WM8960_IFACE1_BCLKINV_SHIFT (7U) +#define WM8960_IFACE1_BCLKINV_SET(x) (((uint16_t)(x) << WM8960_IFACE1_BCLKINV_SHIFT) & WM8960_IFACE1_BCLKINV_MASK) +#define WM8960_IFACE1_BCLKINV_GET(x) (((uint16_t)(x) & WM8960_IFACE1_BCLKINV_MASK) >> WM8960_IFACE1_BCLKINV_SHIFT) + +/* + * MS (RW) + * + * Master / Slave Mode Control + * 0 = Enable slave mode + * 1 = Enable master mode + */ +#define WM8960_IFACE1_MS_MASK (0x40U) +#define WM8960_IFACE1_MS_SHIFT (6U) +#define WM8960_IFACE1_MS_SET(x) (((uint16_t)(x) << WM8960_IFACE1_MS_SHIFT) & WM8960_IFACE1_MS_MASK) +#define WM8960_IFACE1_MS_GET(x) (((uint16_t)(x) & WM8960_IFACE1_MS_MASK) >> WM8960_IFACE1_MS_SHIFT) + +/* + * DLRSWAP (RW) + * + * Left/Right DAC Channel Swap + * 0 = Output left and right data as normal + * 1 = Swap left and right DAC data in audio interface + */ +#define WM8960_IFACE1_DLRSWAP_MASK (0x20U) +#define WM8960_IFACE1_DLRSWAP_SHIFT (5U) +#define WM8960_IFACE1_DLRSWAP_SET(x) (((uint16_t)(x) << WM8960_IFACE1_DLRSWAP_SHIFT) & WM8960_IFACE1_DLRSWAP_MASK) +#define WM8960_IFACE1_DLRSWAP_GET(x) (((uint16_t)(x) & WM8960_IFACE1_DLRSWAP_MASK) >> WM8960_IFACE1_DLRSWAP_SHIFT) + +/* + * LRP (RW) + * + * Right, left and I2S modes – LRCLK polarity + * 0 = normal LRCLK polarity + * 1 = invert LRCLK polarity + * DSP Mode – mode A/B select + * 0 = MSB is available on 2nd BCLK rising edge after LRC rising edge (mode A) + * 1 = MSB is available on 1st BCLK rising edge after LRC rising edge (mode B) + */ +#define WM8960_IFACE1_LRP_MASK (0x10U) +#define WM8960_IFACE1_LRP_SHIFT (4U) +#define WM8960_IFACE1_LRP_SET(x) (((uint16_t)(x) << WM8960_IFACE1_LRP_SHIFT) & WM8960_IFACE1_LRP_MASK) +#define WM8960_IFACE1_LRP_GET(x) (((uint16_t)(x) & WM8960_IFACE1_LRP_MASK) >> WM8960_IFACE1_LRP_SHIFT) + +/* + * WL (RW) + * + * Audio Data Word Length + * 00 = 16 bits + * 01 = 20 bits + * 10 = 24 bits + * 11 = 32 bits (see Note) + */ +#define WM8960_IFACE1_WL_MASK (0xCU) +#define WM8960_IFACE1_WL_SHIFT (2U) +#define WM8960_IFACE1_WL_SET(x) (((uint16_t)(x) << WM8960_IFACE1_WL_SHIFT) & WM8960_IFACE1_WL_MASK) +#define WM8960_IFACE1_WL_GET(x) (((uint16_t)(x) & WM8960_IFACE1_WL_MASK) >> WM8960_IFACE1_WL_SHIFT) + +/* + * FORMAT (RW) + * + * 00 = Right justified + * 01 = Left justified + * 10 = I2S Format + * 11 = DSP Mode + */ +#define WM8960_IFACE1_FORMAT_MASK (0x3U) +#define WM8960_IFACE1_FORMAT_SHIFT (0U) +#define WM8960_IFACE1_FORMAT_SET(x) (((uint16_t)(x) << WM8960_IFACE1_FORMAT_SHIFT) & WM8960_IFACE1_FORMAT_MASK) +#define WM8960_IFACE1_FORMAT_GET(x) (((uint16_t)(x) & WM8960_IFACE1_FORMAT_MASK) >> WM8960_IFACE1_FORMAT_SHIFT) + +/* Bitfield definition for register: CLOCK2 */ +/* + * DCLKDIV (RW) + * + * Class D switching clock divider. + * 000 = SYSCLK / 1.5 (Not recommended) + * 001 = SYSCLK / 2 + * 010 = SYSCLK / 3 + * 011 = SYSCLK / 4 + * 100 = SYSCLK / 6 + * 101 = SYSCLK / 8 + * 110 = SYSCLK / 12 + * 111 = SYSCLK / 16 + */ +#define WM8960_CLOCK2_DCLKDIV_MASK (0x1C0U) +#define WM8960_CLOCK2_DCLKDIV_SHIFT (6U) +#define WM8960_CLOCK2_DCLKDIV_SET(x) (((uint16_t)(x) << WM8960_CLOCK2_DCLKDIV_SHIFT) & WM8960_CLOCK2_DCLKDIV_MASK) +#define WM8960_CLOCK2_DCLKDIV_GET(x) (((uint16_t)(x) & WM8960_CLOCK2_DCLKDIV_MASK) >> WM8960_CLOCK2_DCLKDIV_SHIFT) + +/* + * BCLKDIV (RW) + * + * BCLK Frequency (Master Mode) + * 0000 = SYSCLK + * 0001 = SYSCLK / 1.5 + * 0010 = SYSCLK / 2 + * 0011 = SYSCLK / 3 + * 0100 = SYSCLK / 4 + * 0101 = SYSCLK / 5.5 + * 0110 = SYSCLK / 6 + * 0111 = SYSCLK / 8 + * 1000 = SYSCLK / 11 + * 1001 = SYSCLK / 12 + * 1010 = SYSCLK / 16 + * 1011 = SYSCLK / 22 + * 1100 = SYSCLK / 24 + * 1101 to 1111 = SYSCLK / 32 + */ +#define WM8960_CLOCK2_BCLKDIV_MASK (0xFU) +#define WM8960_CLOCK2_BCLKDIV_SHIFT (0U) +#define WM8960_CLOCK2_BCLKDIV_SET(x) (((uint16_t)(x) << WM8960_CLOCK2_BCLKDIV_SHIFT) & WM8960_CLOCK2_BCLKDIV_MASK) +#define WM8960_CLOCK2_BCLKDIV_GET(x) (((uint16_t)(x) & WM8960_CLOCK2_BCLKDIV_MASK) >> WM8960_CLOCK2_BCLKDIV_SHIFT) + +/* Bitfield definition for register: IFACE2 */ +/* + * ALRCGPIO (RW) + * + * ADCLRC/GPIO1 Pin Function Select + * 0 = ADCLRC frame clock for ADC + * 1 = GPIO pin + */ +#define WM8960_IFACE2_ALRCGPIO_MASK (0x40U) +#define WM8960_IFACE2_ALRCGPIO_SHIFT (6U) +#define WM8960_IFACE2_ALRCGPIO_SET(x) (((uint16_t)(x) << WM8960_IFACE2_ALRCGPIO_SHIFT) & WM8960_IFACE2_ALRCGPIO_MASK) +#define WM8960_IFACE2_ALRCGPIO_GET(x) (((uint16_t)(x) & WM8960_IFACE2_ALRCGPIO_MASK) >> WM8960_IFACE2_ALRCGPIO_SHIFT) + +/* + * WL8 (RW) + * + * 8-Bit Word Length Select (Used with + * companding) + * 0 = Off + * 1 = Device operates in 8-bit mode. + */ +#define WM8960_IFACE2_WL8_MASK (0x20U) +#define WM8960_IFACE2_WL8_SHIFT (5U) +#define WM8960_IFACE2_WL8_SET(x) (((uint16_t)(x) << WM8960_IFACE2_WL8_SHIFT) & WM8960_IFACE2_WL8_MASK) +#define WM8960_IFACE2_WL8_GET(x) (((uint16_t)(x) & WM8960_IFACE2_WL8_MASK) >> WM8960_IFACE2_WL8_SHIFT) + +/* + * DACCOMP (RW) + * + * DAC companding + * 00 = off + * 01 = reserved + * 10 = μ-law + * 11 = A-law + */ +#define WM8960_IFACE2_DACCOMP_MASK (0x18U) +#define WM8960_IFACE2_DACCOMP_SHIFT (3U) +#define WM8960_IFACE2_DACCOMP_SET(x) (((uint16_t)(x) << WM8960_IFACE2_DACCOMP_SHIFT) & WM8960_IFACE2_DACCOMP_MASK) +#define WM8960_IFACE2_DACCOMP_GET(x) (((uint16_t)(x) & WM8960_IFACE2_DACCOMP_MASK) >> WM8960_IFACE2_DACCOMP_SHIFT) + +/* + * ADCCOMP (RW) + * + * ADC companding + * 00 = off + * 01 = reserved + * 10 = μ-law + * 11 = A-law + */ +#define WM8960_IFACE2_ADCCOMP_MASK (0x6U) +#define WM8960_IFACE2_ADCCOMP_SHIFT (1U) +#define WM8960_IFACE2_ADCCOMP_SET(x) (((uint16_t)(x) << WM8960_IFACE2_ADCCOMP_SHIFT) & WM8960_IFACE2_ADCCOMP_MASK) +#define WM8960_IFACE2_ADCCOMP_GET(x) (((uint16_t)(x) & WM8960_IFACE2_ADCCOMP_MASK) >> WM8960_IFACE2_ADCCOMP_SHIFT) + +/* + * LOOPBACK (RW) + * + * Digital Loopback Function + * 0 = No loopback. + * 1 = Loopback enabled, ADC data output is fed + * directly into DAC data input + */ +#define WM8960_IFACE2_LOOPBACK_MASK (0x1U) +#define WM8960_IFACE2_LOOPBACK_SHIFT (0U) +#define WM8960_IFACE2_LOOPBACK_SET(x) (((uint16_t)(x) << WM8960_IFACE2_LOOPBACK_SHIFT) & WM8960_IFACE2_LOOPBACK_MASK) +#define WM8960_IFACE2_LOOPBACK_GET(x) (((uint16_t)(x) & WM8960_IFACE2_LOOPBACK_MASK) >> WM8960_IFACE2_LOOPBACK_SHIFT) + +/* Bitfield definition for register: LDAC */ +/* + * DACVU (RW) + * + * DAC Volume Update + * Writing a 1 to this bit will cause left and right + * DAC volumes to be updated (LDACVOL and RDACVOL) + */ +#define WM8960_LDAC_DACVU_MASK (0x100U) +#define WM8960_LDAC_DACVU_SHIFT (8U) +#define WM8960_LDAC_DACVU_SET(x) (((uint16_t)(x) << WM8960_LDAC_DACVU_SHIFT) & WM8960_LDAC_DACVU_MASK) +#define WM8960_LDAC_DACVU_GET(x) (((uint16_t)(x) & WM8960_LDAC_DACVU_MASK) >> WM8960_LDAC_DACVU_SHIFT) + +/* + * LDACVOL (RW) + * + * Left DAC Digital Volume Control + * 0000 0000 = Digital Mute + * 0000 0001 = -127dB + * 0000 0010 = -126.5dB + * ... 0.5dB steps up to + * 1111 1111 = 0dB + */ +#define WM8960_LDAC_LDACVOL_MASK (0xFFU) +#define WM8960_LDAC_LDACVOL_SHIFT (0U) +#define WM8960_LDAC_LDACVOL_SET(x) (((uint16_t)(x) << WM8960_LDAC_LDACVOL_SHIFT) & WM8960_LDAC_LDACVOL_MASK) +#define WM8960_LDAC_LDACVOL_GET(x) (((uint16_t)(x) & WM8960_LDAC_LDACVOL_MASK) >> WM8960_LDAC_LDACVOL_SHIFT) + +/* Bitfield definition for register: RDAC */ +/* + * DACVU (RW) + * + * DAC Volume Update + * Writing a 1 to this bit will cause left and right + * DAC volumes to be updated (LDACVOL and RDACVOL) + */ +#define WM8960_RDAC_DACVU_MASK (0x100U) +#define WM8960_RDAC_DACVU_SHIFT (8U) +#define WM8960_RDAC_DACVU_SET(x) (((uint16_t)(x) << WM8960_RDAC_DACVU_SHIFT) & WM8960_RDAC_DACVU_MASK) +#define WM8960_RDAC_DACVU_GET(x) (((uint16_t)(x) & WM8960_RDAC_DACVU_MASK) >> WM8960_RDAC_DACVU_SHIFT) + +/* + * RDACVOL (RW) + * + * Right DAC Digital Volume Control + * 0000 0000 = Digital Mute + * 0000 0001 = -127dB + * 0000 0010 = -126.5dB + * ... 0.5dB steps up to + * 1111 1111 = 0dB + */ +#define WM8960_RDAC_RDACVOL_MASK (0xFFU) +#define WM8960_RDAC_RDACVOL_SHIFT (0U) +#define WM8960_RDAC_RDACVOL_SET(x) (((uint16_t)(x) << WM8960_RDAC_RDACVOL_SHIFT) & WM8960_RDAC_RDACVOL_MASK) +#define WM8960_RDAC_RDACVOL_GET(x) (((uint16_t)(x) & WM8960_RDAC_RDACVOL_MASK) >> WM8960_RDAC_RDACVOL_SHIFT) + +/* Bitfield definition for register: RESET */ +/* + * RESET (RW) + * + * Writing to this register resets all registers to their default state. + */ +#define WM8960_RESET_RESET_MASK (0x1FFU) +#define WM8960_RESET_RESET_SHIFT (0U) +#define WM8960_RESET_RESET_SET(x) (((uint16_t)(x) << WM8960_RESET_RESET_SHIFT) & WM8960_RESET_RESET_MASK) +#define WM8960_RESET_RESET_GET(x) (((uint16_t)(x) & WM8960_RESET_RESET_MASK) >> WM8960_RESET_RESET_SHIFT) + +/* Bitfield definition for register: 3D */ +/* + * 3DUC (RW) + * + * 3D Enhance Filter Upper Cut-Off Frequency + * 0 = High (Recommended for fs>=32kHz) + * 1 = Low (Recommended for fs<32kHz) + */ +#define WM8960_3D_3DUC_MASK (0x40U) +#define WM8960_3D_3DUC_SHIFT (6U) +#define WM8960_3D_3DUC_SET(x) (((uint16_t)(x) << WM8960_3D_3DUC_SHIFT) & WM8960_3D_3DUC_MASK) +#define WM8960_3D_3DUC_GET(x) (((uint16_t)(x) & WM8960_3D_3DUC_MASK) >> WM8960_3D_3DUC_SHIFT) + +/* + * 3DLC (RW) + * + * 3D Enhance Filter Lower Cut-Off Frequency + * 0 = Low (Recommended for fs>=32kHz) + * 1 = High (Recommended for fs<32kHz) + */ +#define WM8960_3D_3DLC_MASK (0x20U) +#define WM8960_3D_3DLC_SHIFT (5U) +#define WM8960_3D_3DLC_SET(x) (((uint16_t)(x) << WM8960_3D_3DLC_SHIFT) & WM8960_3D_3DLC_MASK) +#define WM8960_3D_3DLC_GET(x) (((uint16_t)(x) & WM8960_3D_3DLC_MASK) >> WM8960_3D_3DLC_SHIFT) + +/* + * 3DDEPTH (RW) + * + * 3D Stereo Depth + * 0000 = 0% (minimum 3D effect) + * 0001 = 6.67% + * .... + * 1110 = 93.3% + * 1111 = 100% (maximum 3D effect) + */ +#define WM8960_3D_3DDEPTH_MASK (0x1EU) +#define WM8960_3D_3DDEPTH_SHIFT (1U) +#define WM8960_3D_3DDEPTH_SET(x) (((uint16_t)(x) << WM8960_3D_3DDEPTH_SHIFT) & WM8960_3D_3DDEPTH_MASK) +#define WM8960_3D_3DDEPTH_GET(x) (((uint16_t)(x) & WM8960_3D_3DDEPTH_MASK) >> WM8960_3D_3DDEPTH_SHIFT) + +/* + * 3DEN (RW) + * + * 3D Stereo Enhancement Enable + * 0 = Disabled + * 1 = Enabled + */ +#define WM8960_3D_3DEN_MASK (0x1U) +#define WM8960_3D_3DEN_SHIFT (0U) +#define WM8960_3D_3DEN_SET(x) (((uint16_t)(x) << WM8960_3D_3DEN_SHIFT) & WM8960_3D_3DEN_MASK) +#define WM8960_3D_3DEN_GET(x) (((uint16_t)(x) & WM8960_3D_3DEN_MASK) >> WM8960_3D_3DEN_SHIFT) + +/* Bitfield definition for register: ALC1 */ +/* + * ALCSEL (RW) + * + * ALC Function Select + * 00 = ALC off (PGA gain set by register) + * 01 = Right channel only + * 10 = Left channel only + * 11 = Stereo (PGA registers unused) Note: + * ensure that LINVOL and RINVOL settings + * (reg. 0 and 1) are the same before entering this mode. + */ +#define WM8960_ALC1_ALCSEL_MASK (0x180U) +#define WM8960_ALC1_ALCSEL_SHIFT (7U) +#define WM8960_ALC1_ALCSEL_SET(x) (((uint16_t)(x) << WM8960_ALC1_ALCSEL_SHIFT) & WM8960_ALC1_ALCSEL_MASK) +#define WM8960_ALC1_ALCSEL_GET(x) (((uint16_t)(x) & WM8960_ALC1_ALCSEL_MASK) >> WM8960_ALC1_ALCSEL_SHIFT) + +/* + * MAXGAIN (RW) + * + * Set Maximum Gain of PGA (During ALC + * operation) + * 111 : +30dB + * 110 : +24dB + * ….(-6dB steps) + * 001 : -6dB + * 000 : -12dB + */ +#define WM8960_ALC1_MAXGAIN_MASK (0x70U) +#define WM8960_ALC1_MAXGAIN_SHIFT (4U) +#define WM8960_ALC1_MAXGAIN_SET(x) (((uint16_t)(x) << WM8960_ALC1_MAXGAIN_SHIFT) & WM8960_ALC1_MAXGAIN_MASK) +#define WM8960_ALC1_MAXGAIN_GET(x) (((uint16_t)(x) & WM8960_ALC1_MAXGAIN_MASK) >> WM8960_ALC1_MAXGAIN_SHIFT) + +/* + * ALCL (RW) + * + * ALC Target (Sets signal level at ADC input) + * 0000 = -22.5dB FS + * 0001 = -21.0dB FS + * … (1.5dB steps) + * 1101 = -3.0dB FS + * 1110 = -1.5dB FS + * 1111 = -1.5dB FS + */ +#define WM8960_ALC1_ALCL_MASK (0xFU) +#define WM8960_ALC1_ALCL_SHIFT (0U) +#define WM8960_ALC1_ALCL_SET(x) (((uint16_t)(x) << WM8960_ALC1_ALCL_SHIFT) & WM8960_ALC1_ALCL_MASK) +#define WM8960_ALC1_ALCL_GET(x) (((uint16_t)(x) & WM8960_ALC1_ALCL_MASK) >> WM8960_ALC1_ALCL_SHIFT) + +/* Bitfield definition for register: ALC2 */ +/* + * MINGAIN (RW) + * + * Set Minimum Gain of PGA (During ALC + * operation) + * 000 = -17.25dB + * 001 = -11.25dB + * 010 = -5.25dB + * 011 = +0.75dB + * 100 = +6.75dB + * 101 = +12.75dB + * 110 = +18.75dB + * 111 = +24.75dB + */ +#define WM8960_ALC2_MINGAIN_MASK (0x70U) +#define WM8960_ALC2_MINGAIN_SHIFT (4U) +#define WM8960_ALC2_MINGAIN_SET(x) (((uint16_t)(x) << WM8960_ALC2_MINGAIN_SHIFT) & WM8960_ALC2_MINGAIN_MASK) +#define WM8960_ALC2_MINGAIN_GET(x) (((uint16_t)(x) & WM8960_ALC2_MINGAIN_MASK) >> WM8960_ALC2_MINGAIN_SHIFT) + +/* + * HLD (RW) + * + * ALC hold time before gain is increased. + * 0000 = 0ms + * 0001 = 2.67ms + * 0010 = 5.33ms + * … (time doubles with every step) + * 1111 = 43.691s + */ +#define WM8960_ALC2_HLD_MASK (0xFU) +#define WM8960_ALC2_HLD_SHIFT (0U) +#define WM8960_ALC2_HLD_SET(x) (((uint16_t)(x) << WM8960_ALC2_HLD_SHIFT) & WM8960_ALC2_HLD_MASK) +#define WM8960_ALC2_HLD_GET(x) (((uint16_t)(x) & WM8960_ALC2_HLD_MASK) >> WM8960_ALC2_HLD_SHIFT) + +/* Bitfield definition for register: ALC3 */ +/* + * ALCMODE (RW) + * + * Determines the ALC mode of operation: + * 0 = ALC mode + * 1 = Limiter mode + */ +#define WM8960_ALC3_ALCMODE_MASK (0x100U) +#define WM8960_ALC3_ALCMODE_SHIFT (8U) +#define WM8960_ALC3_ALCMODE_SET(x) (((uint16_t)(x) << WM8960_ALC3_ALCMODE_SHIFT) & WM8960_ALC3_ALCMODE_MASK) +#define WM8960_ALC3_ALCMODE_GET(x) (((uint16_t)(x) & WM8960_ALC3_ALCMODE_MASK) >> WM8960_ALC3_ALCMODE_SHIFT) + +/* + * DCY (RW) + * + * ALC decay (gain ramp-up) time + * 0000 = 24ms + * 0001 = 48ms + * 0010 = 96ms + * … (time doubles with every step) + * 1010 or higher = 24.58s + */ +#define WM8960_ALC3_DCY_MASK (0xF0U) +#define WM8960_ALC3_DCY_SHIFT (4U) +#define WM8960_ALC3_DCY_SET(x) (((uint16_t)(x) << WM8960_ALC3_DCY_SHIFT) & WM8960_ALC3_DCY_MASK) +#define WM8960_ALC3_DCY_GET(x) (((uint16_t)(x) & WM8960_ALC3_DCY_MASK) >> WM8960_ALC3_DCY_SHIFT) + +/* + * ATK (RW) + * + * ALC attack (gain ramp-down) time + * 0000 = 6ms + * 0001 = 12ms + * 0010 = 24ms + * … (time doubles with every step) + * 1010 or higher = 6.14s + */ +#define WM8960_ALC3_ATK_MASK (0xFU) +#define WM8960_ALC3_ATK_SHIFT (0U) +#define WM8960_ALC3_ATK_SET(x) (((uint16_t)(x) << WM8960_ALC3_ATK_SHIFT) & WM8960_ALC3_ATK_MASK) +#define WM8960_ALC3_ATK_GET(x) (((uint16_t)(x) & WM8960_ALC3_ATK_MASK) >> WM8960_ALC3_ATK_SHIFT) + +/* Bitfield definition for register: NOISEG */ +/* + * NGTH (RW) + * + * Noise gate threshold + * 00000 -76.5dBfs + * 00001 -75dBfs + * … 1.5 dB steps + * 11110 -31.5dBfs + * 11111 -30dBfs + */ +#define WM8960_NOISEG_NGTH_MASK (0xF8U) +#define WM8960_NOISEG_NGTH_SHIFT (3U) +#define WM8960_NOISEG_NGTH_SET(x) (((uint16_t)(x) << WM8960_NOISEG_NGTH_SHIFT) & WM8960_NOISEG_NGTH_MASK) +#define WM8960_NOISEG_NGTH_GET(x) (((uint16_t)(x) & WM8960_NOISEG_NGTH_MASK) >> WM8960_NOISEG_NGTH_SHIFT) + +/* + * NGAT (RW) + * + * Noise gate function enable + * 0 = disable + * 1 = enable + */ +#define WM8960_NOISEG_NGAT_MASK (0x1U) +#define WM8960_NOISEG_NGAT_SHIFT (0U) +#define WM8960_NOISEG_NGAT_SET(x) (((uint16_t)(x) << WM8960_NOISEG_NGAT_SHIFT) & WM8960_NOISEG_NGAT_MASK) +#define WM8960_NOISEG_NGAT_GET(x) (((uint16_t)(x) & WM8960_NOISEG_NGAT_MASK) >> WM8960_NOISEG_NGAT_SHIFT) + +/* Bitfield definition for register: LADC */ +/* + * ADCVU (RW) + * + * ADC Volume Update + * Writing a 1 to this bit will cause left and right + * ADC volumes to be updated (LADCVOL and + * RADCVOL) + */ +#define WM8960_LADC_ADCVU_MASK (0x100U) +#define WM8960_LADC_ADCVU_SHIFT (8U) +#define WM8960_LADC_ADCVU_SET(x) (((uint16_t)(x) << WM8960_LADC_ADCVU_SHIFT) & WM8960_LADC_ADCVU_MASK) +#define WM8960_LADC_ADCVU_GET(x) (((uint16_t)(x) & WM8960_LADC_ADCVU_MASK) >> WM8960_LADC_ADCVU_SHIFT) + +/* + * LADCVOL (RW) + * + * Left ADC Digital Volume Control + * 0000 0000 = Digital Mute + * 0000 0001 = -97dB + * 0000 0010 = -96.5dB + * ... 0.5dB steps up to + * 1111 1111 = +30dB + */ +#define WM8960_LADC_LADCVOL_MASK (0xFFU) +#define WM8960_LADC_LADCVOL_SHIFT (0U) +#define WM8960_LADC_LADCVOL_SET(x) (((uint16_t)(x) << WM8960_LADC_LADCVOL_SHIFT) & WM8960_LADC_LADCVOL_MASK) +#define WM8960_LADC_LADCVOL_GET(x) (((uint16_t)(x) & WM8960_LADC_LADCVOL_MASK) >> WM8960_LADC_LADCVOL_SHIFT) + +/* Bitfield definition for register: RADC */ +/* + * ADCVU (RW) + * + * ADC Volume Update + * Writing a 1 to this bit will cause left and right + * ADC volumes to be updated (LADCVOL and RADCVOL) + */ +#define WM8960_RADC_ADCVU_MASK (0x100U) +#define WM8960_RADC_ADCVU_SHIFT (8U) +#define WM8960_RADC_ADCVU_SET(x) (((uint16_t)(x) << WM8960_RADC_ADCVU_SHIFT) & WM8960_RADC_ADCVU_MASK) +#define WM8960_RADC_ADCVU_GET(x) (((uint16_t)(x) & WM8960_RADC_ADCVU_MASK) >> WM8960_RADC_ADCVU_SHIFT) + +/* + * RADCVOL (RW) + * + * Right ADC Digital Volume Control + * 0000 0000 = Digital Mute + * 0000 0001 = -97dB + * 0000 0010 = -96.5dB + * ... 0.5dB steps up to + * 1111 1111 = +30dB + */ +#define WM8960_RADC_RADCVOL_MASK (0xFFU) +#define WM8960_RADC_RADCVOL_SHIFT (0U) +#define WM8960_RADC_RADCVOL_SET(x) (((uint16_t)(x) << WM8960_RADC_RADCVOL_SHIFT) & WM8960_RADC_RADCVOL_MASK) +#define WM8960_RADC_RADCVOL_GET(x) (((uint16_t)(x) & WM8960_RADC_RADCVOL_MASK) >> WM8960_RADC_RADCVOL_SHIFT) + +/* Bitfield definition for register: ADDCTL1 */ +/* + * TSDEN (RW) + * + * Thermal Shutdown Enable + * 0 = Thermal shutdown disabled + * 1 = Thermal shutdown enabled + * (TSENSEN must be enabled for this function to work) + */ +#define WM8960_ADDCTL1_TSDEN_MASK (0x100U) +#define WM8960_ADDCTL1_TSDEN_SHIFT (8U) +#define WM8960_ADDCTL1_TSDEN_SET(x) (((uint16_t)(x) << WM8960_ADDCTL1_TSDEN_SHIFT) & WM8960_ADDCTL1_TSDEN_MASK) +#define WM8960_ADDCTL1_TSDEN_GET(x) (((uint16_t)(x) & WM8960_ADDCTL1_TSDEN_MASK) >> WM8960_ADDCTL1_TSDEN_SHIFT) + +/* + * VSEL (RW) + * + * Analogue Bias Optimisation + * 00 = Reserved + * 01 = Increased bias current optimized for + * AVDD=2.7V + * 1X = Lowest bias current, optimized for + * AVDD=3.3V + */ +#define WM8960_ADDCTL1_VSEL_MASK (0xC0U) +#define WM8960_ADDCTL1_VSEL_SHIFT (6U) +#define WM8960_ADDCTL1_VSEL_SET(x) (((uint16_t)(x) << WM8960_ADDCTL1_VSEL_SHIFT) & WM8960_ADDCTL1_VSEL_MASK) +#define WM8960_ADDCTL1_VSEL_GET(x) (((uint16_t)(x) & WM8960_ADDCTL1_VSEL_MASK) >> WM8960_ADDCTL1_VSEL_SHIFT) + +/* + * DMONOMIX (RW) + * + * DAC Mono Mix + * 0 = Stereo + * 1 = Mono (Mono MIX output on enabled DACs + */ +#define WM8960_ADDCTL1_DMONOMIX_MASK (0x10U) +#define WM8960_ADDCTL1_DMONOMIX_SHIFT (4U) +#define WM8960_ADDCTL1_DMONOMIX_SET(x) (((uint16_t)(x) << WM8960_ADDCTL1_DMONOMIX_SHIFT) & WM8960_ADDCTL1_DMONOMIX_MASK) +#define WM8960_ADDCTL1_DMONOMIX_GET(x) (((uint16_t)(x) & WM8960_ADDCTL1_DMONOMIX_MASK) >> WM8960_ADDCTL1_DMONOMIX_SHIFT) + +/* + * DATSEL (RW) + * + * ADC Data Output Select + * 00: left data = left ADC; right data =right ADC + * 01: left data = left ADC; right data = left ADC + * 10: left data = right ADC; right data =right ADC + * 11: left data = right ADC; right data = left ADC + */ +#define WM8960_ADDCTL1_DATSEL_MASK (0xCU) +#define WM8960_ADDCTL1_DATSEL_SHIFT (2U) +#define WM8960_ADDCTL1_DATSEL_SET(x) (((uint16_t)(x) << WM8960_ADDCTL1_DATSEL_SHIFT) & WM8960_ADDCTL1_DATSEL_MASK) +#define WM8960_ADDCTL1_DATSEL_GET(x) (((uint16_t)(x) & WM8960_ADDCTL1_DATSEL_MASK) >> WM8960_ADDCTL1_DATSEL_SHIFT) + +/* + * TOCLKSEL (RW) + * + * Slow Clock Select (Used for volume update + * timeouts and for jack detect debounce) + * 0 = SYSCLK / 221 (Slower Response) + * 1 = SYSCLK / 219 (Faster Response) + */ +#define WM8960_ADDCTL1_TOCLKSEL_MASK (0x2U) +#define WM8960_ADDCTL1_TOCLKSEL_SHIFT (1U) +#define WM8960_ADDCTL1_TOCLKSEL_SET(x) (((uint16_t)(x) << WM8960_ADDCTL1_TOCLKSEL_SHIFT) & WM8960_ADDCTL1_TOCLKSEL_MASK) +#define WM8960_ADDCTL1_TOCLKSEL_GET(x) (((uint16_t)(x) & WM8960_ADDCTL1_TOCLKSEL_MASK) >> WM8960_ADDCTL1_TOCLKSEL_SHIFT) + +/* + * TOEN (RW) + * + * Enables Slow Clock for Volume Update Timeout + * and Jack Detect Debounce + * 0 = Slow clock disabled + * 1 = Slow clock enabled + */ +#define WM8960_ADDCTL1_TOEN_MASK (0x1U) +#define WM8960_ADDCTL1_TOEN_SHIFT (0U) +#define WM8960_ADDCTL1_TOEN_SET(x) (((uint16_t)(x) << WM8960_ADDCTL1_TOEN_SHIFT) & WM8960_ADDCTL1_TOEN_MASK) +#define WM8960_ADDCTL1_TOEN_GET(x) (((uint16_t)(x) & WM8960_ADDCTL1_TOEN_MASK) >> WM8960_ADDCTL1_TOEN_SHIFT) + +/* Bitfield definition for register: ADDCTL2 */ +/* + * HPSWEN (RW) + * + * Headphone Switch Enable + * 0 = Headphone switch disabled + * 1 = Headphone switch enabled + */ +#define WM8960_ADDCTL2_HPSWEN_MASK (0x40U) +#define WM8960_ADDCTL2_HPSWEN_SHIFT (6U) +#define WM8960_ADDCTL2_HPSWEN_SET(x) (((uint16_t)(x) << WM8960_ADDCTL2_HPSWEN_SHIFT) & WM8960_ADDCTL2_HPSWEN_MASK) +#define WM8960_ADDCTL2_HPSWEN_GET(x) (((uint16_t)(x) & WM8960_ADDCTL2_HPSWEN_MASK) >> WM8960_ADDCTL2_HPSWEN_SHIFT) + +/* + * HPSWPOL (RW) + * + * Headphone Switch Polarity + * 0 = HPDETECT high = headphone + * 1 = HPDETECT high = speaker + */ +#define WM8960_ADDCTL2_HPSWPOL_MASK (0x20U) +#define WM8960_ADDCTL2_HPSWPOL_SHIFT (5U) +#define WM8960_ADDCTL2_HPSWPOL_SET(x) (((uint16_t)(x) << WM8960_ADDCTL2_HPSWPOL_SHIFT) & WM8960_ADDCTL2_HPSWPOL_MASK) +#define WM8960_ADDCTL2_HPSWPOL_GET(x) (((uint16_t)(x) & WM8960_ADDCTL2_HPSWPOL_MASK) >> WM8960_ADDCTL2_HPSWPOL_SHIFT) + +/* + * TRIS (RW) + * + * Tristates ADCDAT and switches ADCLRC, + * DACLRC and BCLK to inputs. + * 0 = ADCDAT is an output; ADCLRC, DACLRC + * and BCLK are inputs (slave mode) or outputs + * (master mode) + * 1 = ADCDAT is tristated; DACLRC and BCLK + * are inputs; ADCLRC is an input (when not + * configured as a GPIO) + */ +#define WM8960_ADDCTL2_TRIS_MASK (0x8U) +#define WM8960_ADDCTL2_TRIS_SHIFT (3U) +#define WM8960_ADDCTL2_TRIS_SET(x) (((uint16_t)(x) << WM8960_ADDCTL2_TRIS_SHIFT) & WM8960_ADDCTL2_TRIS_MASK) +#define WM8960_ADDCTL2_TRIS_GET(x) (((uint16_t)(x) & WM8960_ADDCTL2_TRIS_MASK) >> WM8960_ADDCTL2_TRIS_SHIFT) + +/* + * LRCM (RW) + * + * Selects disable mode for ADCLRC and DACLRC + * (Master mode) + * 0 = ADCLRC disabled when ADC (Left and + * Right) disabled; DACLRC disabled when + * DAC (Left and Right) disabled. + * 1 = ADCLRC and DACLRC disabled only when + * ADC (Left and Right) and DAC (Left and Right) + * are disabled. + */ +#define WM8960_ADDCTL2_LRCM_MASK (0x4U) +#define WM8960_ADDCTL2_LRCM_SHIFT (2U) +#define WM8960_ADDCTL2_LRCM_SET(x) (((uint16_t)(x) << WM8960_ADDCTL2_LRCM_SHIFT) & WM8960_ADDCTL2_LRCM_MASK) +#define WM8960_ADDCTL2_LRCM_GET(x) (((uint16_t)(x) & WM8960_ADDCTL2_LRCM_MASK) >> WM8960_ADDCTL2_LRCM_SHIFT) + +/* Bitfield definition for register: POWER1 */ +/* + * VMIDSEL (RW) + * + * Vmid Divider Enable and Select + * 00 = Vmid disabled (for OFF mode) + * 01 = 2 x 50k divider enabled (for playback / + * record) + * 10 = 2 x 250k divider enabled (for low-power + * standby) + * 11 = 2 x 5k divider enabled (for fast start-up) + */ +#define WM8960_POWER1_VMIDSEL_MASK (0x180U) +#define WM8960_POWER1_VMIDSEL_SHIFT (7U) +#define WM8960_POWER1_VMIDSEL_SET(x) (((uint16_t)(x) << WM8960_POWER1_VMIDSEL_SHIFT) & WM8960_POWER1_VMIDSEL_MASK) +#define WM8960_POWER1_VMIDSEL_GET(x) (((uint16_t)(x) & WM8960_POWER1_VMIDSEL_MASK) >> WM8960_POWER1_VMIDSEL_SHIFT) + +/* + * VREF (RW) + * + * VREF (necessary for all other functions) + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER1_VREF_MASK (0x40U) +#define WM8960_POWER1_VREF_SHIFT (6U) +#define WM8960_POWER1_VREF_SET(x) (((uint16_t)(x) << WM8960_POWER1_VREF_SHIFT) & WM8960_POWER1_VREF_MASK) +#define WM8960_POWER1_VREF_GET(x) (((uint16_t)(x) & WM8960_POWER1_VREF_MASK) >> WM8960_POWER1_VREF_SHIFT) + +/* + * AINL (RW) + * + * Analogue in PGA Left + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER1_AINL_MASK (0x20U) +#define WM8960_POWER1_AINL_SHIFT (5U) +#define WM8960_POWER1_AINL_SET(x) (((uint16_t)(x) << WM8960_POWER1_AINL_SHIFT) & WM8960_POWER1_AINL_MASK) +#define WM8960_POWER1_AINL_GET(x) (((uint16_t)(x) & WM8960_POWER1_AINL_MASK) >> WM8960_POWER1_AINL_SHIFT) + +/* + * AINR (RW) + * + * Analogue in PGA Right + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER1_AINR_MASK (0x10U) +#define WM8960_POWER1_AINR_SHIFT (4U) +#define WM8960_POWER1_AINR_SET(x) (((uint16_t)(x) << WM8960_POWER1_AINR_SHIFT) & WM8960_POWER1_AINR_MASK) +#define WM8960_POWER1_AINR_GET(x) (((uint16_t)(x) & WM8960_POWER1_AINR_MASK) >> WM8960_POWER1_AINR_SHIFT) + +/* + * ADCL (RW) + * + * ADC Left + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER1_ADCL_MASK (0x8U) +#define WM8960_POWER1_ADCL_SHIFT (3U) +#define WM8960_POWER1_ADCL_SET(x) (((uint16_t)(x) << WM8960_POWER1_ADCL_SHIFT) & WM8960_POWER1_ADCL_MASK) +#define WM8960_POWER1_ADCL_GET(x) (((uint16_t)(x) & WM8960_POWER1_ADCL_MASK) >> WM8960_POWER1_ADCL_SHIFT) + +/* + * ADCR (RW) + * + * ADC Right + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER1_ADCR_MASK (0x4U) +#define WM8960_POWER1_ADCR_SHIFT (2U) +#define WM8960_POWER1_ADCR_SET(x) (((uint16_t)(x) << WM8960_POWER1_ADCR_SHIFT) & WM8960_POWER1_ADCR_MASK) +#define WM8960_POWER1_ADCR_GET(x) (((uint16_t)(x) & WM8960_POWER1_ADCR_MASK) >> WM8960_POWER1_ADCR_SHIFT) + +/* + * MICB (RW) + * + * MICBIAS + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER1_MICB_MASK (0x2U) +#define WM8960_POWER1_MICB_SHIFT (1U) +#define WM8960_POWER1_MICB_SET(x) (((uint16_t)(x) << WM8960_POWER1_MICB_SHIFT) & WM8960_POWER1_MICB_MASK) +#define WM8960_POWER1_MICB_GET(x) (((uint16_t)(x) & WM8960_POWER1_MICB_MASK) >> WM8960_POWER1_MICB_SHIFT) + +/* + * DIGENB (RW) + * + * Master Clock Disable + * 0 = Master clock enabled + * 1 = Master clock disabled + */ +#define WM8960_POWER1_DIGENB_MASK (0x1U) +#define WM8960_POWER1_DIGENB_SHIFT (0U) +#define WM8960_POWER1_DIGENB_SET(x) (((uint16_t)(x) << WM8960_POWER1_DIGENB_SHIFT) & WM8960_POWER1_DIGENB_MASK) +#define WM8960_POWER1_DIGENB_GET(x) (((uint16_t)(x) & WM8960_POWER1_DIGENB_MASK) >> WM8960_POWER1_DIGENB_SHIFT) + +/* Bitfield definition for register: POWER2 */ +/* + * DACL (RW) + * + * DAC Left + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER2_DACL_MASK (0x100U) +#define WM8960_POWER2_DACL_SHIFT (8U) +#define WM8960_POWER2_DACL_SET(x) (((uint16_t)(x) << WM8960_POWER2_DACL_SHIFT) & WM8960_POWER2_DACL_MASK) +#define WM8960_POWER2_DACL_GET(x) (((uint16_t)(x) & WM8960_POWER2_DACL_MASK) >> WM8960_POWER2_DACL_SHIFT) + +/* + * DACR (RW) + * + * DAC Right + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER2_DACR_MASK (0x80U) +#define WM8960_POWER2_DACR_SHIFT (7U) +#define WM8960_POWER2_DACR_SET(x) (((uint16_t)(x) << WM8960_POWER2_DACR_SHIFT) & WM8960_POWER2_DACR_MASK) +#define WM8960_POWER2_DACR_GET(x) (((uint16_t)(x) & WM8960_POWER2_DACR_MASK) >> WM8960_POWER2_DACR_SHIFT) + +/* + * LOUT1 (RW) + * + * LOUT1 Output Buffer + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER2_LOUT1_MASK (0x40U) +#define WM8960_POWER2_LOUT1_SHIFT (6U) +#define WM8960_POWER2_LOUT1_SET(x) (((uint16_t)(x) << WM8960_POWER2_LOUT1_SHIFT) & WM8960_POWER2_LOUT1_MASK) +#define WM8960_POWER2_LOUT1_GET(x) (((uint16_t)(x) & WM8960_POWER2_LOUT1_MASK) >> WM8960_POWER2_LOUT1_SHIFT) + +/* + * ROUT1 (RW) + * + * ROUT1 Output Buffer + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER2_ROUT1_MASK (0x20U) +#define WM8960_POWER2_ROUT1_SHIFT (5U) +#define WM8960_POWER2_ROUT1_SET(x) (((uint16_t)(x) << WM8960_POWER2_ROUT1_SHIFT) & WM8960_POWER2_ROUT1_MASK) +#define WM8960_POWER2_ROUT1_GET(x) (((uint16_t)(x) & WM8960_POWER2_ROUT1_MASK) >> WM8960_POWER2_ROUT1_SHIFT) + +/* + * SPKL (RW) + * + * SPK_LP/SPK_LN Output Buffers + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER2_SPKL_MASK (0x10U) +#define WM8960_POWER2_SPKL_SHIFT (4U) +#define WM8960_POWER2_SPKL_SET(x) (((uint16_t)(x) << WM8960_POWER2_SPKL_SHIFT) & WM8960_POWER2_SPKL_MASK) +#define WM8960_POWER2_SPKL_GET(x) (((uint16_t)(x) & WM8960_POWER2_SPKL_MASK) >> WM8960_POWER2_SPKL_SHIFT) + +/* + * SPKR (RW) + * + * SPK_RP/SPK_RN Output Buffers + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER2_SPKR_MASK (0x8U) +#define WM8960_POWER2_SPKR_SHIFT (3U) +#define WM8960_POWER2_SPKR_SET(x) (((uint16_t)(x) << WM8960_POWER2_SPKR_SHIFT) & WM8960_POWER2_SPKR_MASK) +#define WM8960_POWER2_SPKR_GET(x) (((uint16_t)(x) & WM8960_POWER2_SPKR_MASK) >> WM8960_POWER2_SPKR_SHIFT) + +/* + * OUT3 (RW) + * + * OUT3 Output Buffer + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER2_OUT3_MASK (0x2U) +#define WM8960_POWER2_OUT3_SHIFT (1U) +#define WM8960_POWER2_OUT3_SET(x) (((uint16_t)(x) << WM8960_POWER2_OUT3_SHIFT) & WM8960_POWER2_OUT3_MASK) +#define WM8960_POWER2_OUT3_GET(x) (((uint16_t)(x) & WM8960_POWER2_OUT3_MASK) >> WM8960_POWER2_OUT3_SHIFT) + +/* + * PLL_EN (RW) + * + * PLL Enable + * 0 = Power down + * 1 = Power up + */ +#define WM8960_POWER2_PLL_EN_MASK (0x1U) +#define WM8960_POWER2_PLL_EN_SHIFT (0U) +#define WM8960_POWER2_PLL_EN_SET(x) (((uint16_t)(x) << WM8960_POWER2_PLL_EN_SHIFT) & WM8960_POWER2_PLL_EN_MASK) +#define WM8960_POWER2_PLL_EN_GET(x) (((uint16_t)(x) & WM8960_POWER2_PLL_EN_MASK) >> WM8960_POWER2_PLL_EN_SHIFT) + +/* Bitfield definition for register: ADDCTL3 */ +/* + * VROI (RW) + * + * VREF to Analogue Output Resistance (Disabled + * Outputs) + * 0 = 500 VMID to output + * 1 = 20k VMID to output + */ +#define WM8960_ADDCTL3_VROI_MASK (0x40U) +#define WM8960_ADDCTL3_VROI_SHIFT (6U) +#define WM8960_ADDCTL3_VROI_SET(x) (((uint16_t)(x) << WM8960_ADDCTL3_VROI_SHIFT) & WM8960_ADDCTL3_VROI_MASK) +#define WM8960_ADDCTL3_VROI_GET(x) (((uint16_t)(x) & WM8960_ADDCTL3_VROI_MASK) >> WM8960_ADDCTL3_VROI_SHIFT) + +/* + * OUT3CAP (RW) + * + * Capless Mode Headphone Switch Enable + * 0 = OUT3 unaffected by jack detect events + * 1 = OUT3 enabled and disabled together with + * HP_L and HP_R in response to jack detect + * events + */ +#define WM8960_ADDCTL3_OUT3CAP_MASK (0x8U) +#define WM8960_ADDCTL3_OUT3CAP_SHIFT (3U) +#define WM8960_ADDCTL3_OUT3CAP_SET(x) (((uint16_t)(x) << WM8960_ADDCTL3_OUT3CAP_SHIFT) & WM8960_ADDCTL3_OUT3CAP_MASK) +#define WM8960_ADDCTL3_OUT3CAP_GET(x) (((uint16_t)(x) & WM8960_ADDCTL3_OUT3CAP_MASK) >> WM8960_ADDCTL3_OUT3CAP_SHIFT) + +/* + * ADC_ALC_SR (RW) + * + * ALC Sample Rate + * 000 = 44.1k / 48k + * 001 = 32k + * 010 = 22.05k / 24k + * 011 = 16k + * 100 = 11.25k / 12k + * 101 = 8k + * 110 and 111 = Reserved + */ +#define WM8960_ADDCTL3_ADC_ALC_SR_MASK (0x7U) +#define WM8960_ADDCTL3_ADC_ALC_SR_SHIFT (0U) +#define WM8960_ADDCTL3_ADC_ALC_SR_SET(x) (((uint16_t)(x) << WM8960_ADDCTL3_ADC_ALC_SR_SHIFT) & WM8960_ADDCTL3_ADC_ALC_SR_MASK) +#define WM8960_ADDCTL3_ADC_ALC_SR_GET(x) (((uint16_t)(x) & WM8960_ADDCTL3_ADC_ALC_SR_MASK) >> WM8960_ADDCTL3_ADC_ALC_SR_SHIFT) + +/* Bitfield definition for register: APOP1 */ +/* + * POBCTRL (RW) + * + * Selects the bias current source for output + * amplifiers and VMID buffer + * 0 = VMID / R bias + * 1 = VGS / R bias + */ +#define WM8960_APOP1_POBCTRL_MASK (0x80U) +#define WM8960_APOP1_POBCTRL_SHIFT (7U) +#define WM8960_APOP1_POBCTRL_SET(x) (((uint16_t)(x) << WM8960_APOP1_POBCTRL_SHIFT) & WM8960_APOP1_POBCTRL_MASK) +#define WM8960_APOP1_POBCTRL_GET(x) (((uint16_t)(x) & WM8960_APOP1_POBCTRL_MASK) >> WM8960_APOP1_POBCTRL_SHIFT) + +/* + * BUFDCOPEN (RW) + * + * Enables the VGS / R current generator + * 0 = Disabled + * 1 = Enabled + */ +#define WM8960_APOP1_BUFDCOPEN_MASK (0x10U) +#define WM8960_APOP1_BUFDCOPEN_SHIFT (4U) +#define WM8960_APOP1_BUFDCOPEN_SET(x) (((uint16_t)(x) << WM8960_APOP1_BUFDCOPEN_SHIFT) & WM8960_APOP1_BUFDCOPEN_MASK) +#define WM8960_APOP1_BUFDCOPEN_GET(x) (((uint16_t)(x) & WM8960_APOP1_BUFDCOPEN_MASK) >> WM8960_APOP1_BUFDCOPEN_SHIFT) + +/* + * BUFIOEN (RW) + * + * Enables the VGS / R current generator and the + * analogue input and output bias + * 0 = Disabled + * 1 = Enabled + */ +#define WM8960_APOP1_BUFIOEN_MASK (0x8U) +#define WM8960_APOP1_BUFIOEN_SHIFT (3U) +#define WM8960_APOP1_BUFIOEN_SET(x) (((uint16_t)(x) << WM8960_APOP1_BUFIOEN_SHIFT) & WM8960_APOP1_BUFIOEN_MASK) +#define WM8960_APOP1_BUFIOEN_GET(x) (((uint16_t)(x) & WM8960_APOP1_BUFIOEN_MASK) >> WM8960_APOP1_BUFIOEN_SHIFT) + +/* + * SOFT_ST (RW) + * + * Enables VMID soft start + * 0 = Disabled + * 1 = Enabled + */ +#define WM8960_APOP1_SOFT_ST_MASK (0x4U) +#define WM8960_APOP1_SOFT_ST_SHIFT (2U) +#define WM8960_APOP1_SOFT_ST_SET(x) (((uint16_t)(x) << WM8960_APOP1_SOFT_ST_SHIFT) & WM8960_APOP1_SOFT_ST_MASK) +#define WM8960_APOP1_SOFT_ST_GET(x) (((uint16_t)(x) & WM8960_APOP1_SOFT_ST_MASK) >> WM8960_APOP1_SOFT_ST_SHIFT) + +/* + * HPSTBY (RW) + * + * Headphone Amplifier Standby + * 0 = Standby mode disabled (Normal operation) + * 1 = Standby mode enabled + */ +#define WM8960_APOP1_HPSTBY_MASK (0x1U) +#define WM8960_APOP1_HPSTBY_SHIFT (0U) +#define WM8960_APOP1_HPSTBY_SET(x) (((uint16_t)(x) << WM8960_APOP1_HPSTBY_SHIFT) & WM8960_APOP1_HPSTBY_MASK) +#define WM8960_APOP1_HPSTBY_GET(x) (((uint16_t)(x) & WM8960_APOP1_HPSTBY_MASK) >> WM8960_APOP1_HPSTBY_SHIFT) + +/* Bitfield definition for register: APOP2 */ +/* + * DISOP (RW) + * + * Discharges the DC-blocking headphone + * capacitors on HP_L and HP_R + * 0 = Disabled + * 1 = Enabled + */ +#define WM8960_APOP2_DISOP_MASK (0x40U) +#define WM8960_APOP2_DISOP_SHIFT (6U) +#define WM8960_APOP2_DISOP_SET(x) (((uint16_t)(x) << WM8960_APOP2_DISOP_SHIFT) & WM8960_APOP2_DISOP_MASK) +#define WM8960_APOP2_DISOP_GET(x) (((uint16_t)(x) & WM8960_APOP2_DISOP_MASK) >> WM8960_APOP2_DISOP_SHIFT) + +/* + * DRES (RW) + * + * DRES determines the value of the resistors used + * to discharge the DC-blocking headphone + * capacitors when DISOP=1 + * DRES[1:0] Resistance (Ohms) + * 0 0 400 + * 0 1 200 + * 1 0 600 + * 1 1 150 + */ +#define WM8960_APOP2_DRES_MASK (0x30U) +#define WM8960_APOP2_DRES_SHIFT (4U) +#define WM8960_APOP2_DRES_SET(x) (((uint16_t)(x) << WM8960_APOP2_DRES_SHIFT) & WM8960_APOP2_DRES_MASK) +#define WM8960_APOP2_DRES_GET(x) (((uint16_t)(x) & WM8960_APOP2_DRES_MASK) >> WM8960_APOP2_DRES_SHIFT) + +/* Bitfield definition for register: LINPATH */ +/* + * LMN1 (RW) + * + * Connect LINPUT1 to inverting input of Left Input + * PGA + * 0 = LINPUT1 not connected to PGA + * 1 = LINPUT1 connected to PGA + */ +#define WM8960_LINPATH_LMN1_MASK (0x100U) +#define WM8960_LINPATH_LMN1_SHIFT (8U) +#define WM8960_LINPATH_LMN1_SET(x) (((uint16_t)(x) << WM8960_LINPATH_LMN1_SHIFT) & WM8960_LINPATH_LMN1_MASK) +#define WM8960_LINPATH_LMN1_GET(x) (((uint16_t)(x) & WM8960_LINPATH_LMN1_MASK) >> WM8960_LINPATH_LMN1_SHIFT) + +/* + * LMP3 (RW) + * + * Connect LINPUT3 to non-inverting input of Left + * Input PGA + * 0 = LINPUT3 not connected to PGA + * 1 = LINPUT3 connected to PGA (Constant input + * impedance) + */ +#define WM8960_LINPATH_LMP3_MASK (0x80U) +#define WM8960_LINPATH_LMP3_SHIFT (7U) +#define WM8960_LINPATH_LMP3_SET(x) (((uint16_t)(x) << WM8960_LINPATH_LMP3_SHIFT) & WM8960_LINPATH_LMP3_MASK) +#define WM8960_LINPATH_LMP3_GET(x) (((uint16_t)(x) & WM8960_LINPATH_LMP3_MASK) >> WM8960_LINPATH_LMP3_SHIFT) + +/* + * LMP2 (RW) + * + * Connect LINPUT2 to non-inverting input of Left + * Input PGA + * 0 = LINPUT2 not connected to PGA + * 1 = LINPUT2 connected to PGA (Constant input impedance) + */ +#define WM8960_LINPATH_LMP2_MASK (0x40U) +#define WM8960_LINPATH_LMP2_SHIFT (6U) +#define WM8960_LINPATH_LMP2_SET(x) (((uint16_t)(x) << WM8960_LINPATH_LMP2_SHIFT) & WM8960_LINPATH_LMP2_MASK) +#define WM8960_LINPATH_LMP2_GET(x) (((uint16_t)(x) & WM8960_LINPATH_LMP2_MASK) >> WM8960_LINPATH_LMP2_SHIFT) + +/* + * LMICBOOST (RW) + * + * Left Channel Input PGA Boost Gain + * 00 = +0dB + * 01 = +13dB + * 10 = +20dB + * 11 = +29dB + */ +#define WM8960_LINPATH_LMICBOOST_MASK (0x30U) +#define WM8960_LINPATH_LMICBOOST_SHIFT (4U) +#define WM8960_LINPATH_LMICBOOST_SET(x) (((uint16_t)(x) << WM8960_LINPATH_LMICBOOST_SHIFT) & WM8960_LINPATH_LMICBOOST_MASK) +#define WM8960_LINPATH_LMICBOOST_GET(x) (((uint16_t)(x) & WM8960_LINPATH_LMICBOOST_MASK) >> WM8960_LINPATH_LMICBOOST_SHIFT) + +/* + * LMIC2B (RW) + * + * Connect Left Input PGA to Left Input Boost Mixer + * 0 = Not connected + * 1 = Connected + */ +#define WM8960_LINPATH_LMIC2B_MASK (0x8U) +#define WM8960_LINPATH_LMIC2B_SHIFT (3U) +#define WM8960_LINPATH_LMIC2B_SET(x) (((uint16_t)(x) << WM8960_LINPATH_LMIC2B_SHIFT) & WM8960_LINPATH_LMIC2B_MASK) +#define WM8960_LINPATH_LMIC2B_GET(x) (((uint16_t)(x) & WM8960_LINPATH_LMIC2B_MASK) >> WM8960_LINPATH_LMIC2B_SHIFT) + +/* Bitfield definition for register: RINPATH */ +/* + * RMN1 (RW) + * + * Connect RINPUT1 to inverting input of Right + * Input PGA + * 0 = RINPUT1 not connected to PGA + * 1 = RINPUT1 connected to PGA + */ +#define WM8960_RINPATH_RMN1_MASK (0x100U) +#define WM8960_RINPATH_RMN1_SHIFT (8U) +#define WM8960_RINPATH_RMN1_SET(x) (((uint16_t)(x) << WM8960_RINPATH_RMN1_SHIFT) & WM8960_RINPATH_RMN1_MASK) +#define WM8960_RINPATH_RMN1_GET(x) (((uint16_t)(x) & WM8960_RINPATH_RMN1_MASK) >> WM8960_RINPATH_RMN1_SHIFT) + +/* + * RMP3 (RW) + * + * Connect RINPUT3 to non-inverting input of Right + * Input PGA + * 0 = RINPUT3 not connected to PGA + * 1 = RINPUT3 connected to PGA (Constant input impedance) + */ +#define WM8960_RINPATH_RMP3_MASK (0x80U) +#define WM8960_RINPATH_RMP3_SHIFT (7U) +#define WM8960_RINPATH_RMP3_SET(x) (((uint16_t)(x) << WM8960_RINPATH_RMP3_SHIFT) & WM8960_RINPATH_RMP3_MASK) +#define WM8960_RINPATH_RMP3_GET(x) (((uint16_t)(x) & WM8960_RINPATH_RMP3_MASK) >> WM8960_RINPATH_RMP3_SHIFT) + +/* + * RMP2 (RW) + * + * Connect RINPUT2 to non-inverting input of Right + * Input PGA + * 0 = RINPUT2 not connected to PGA + * 1 = RINPUT2 connected to PGA (Constant input + * impedance) + */ +#define WM8960_RINPATH_RMP2_MASK (0x40U) +#define WM8960_RINPATH_RMP2_SHIFT (6U) +#define WM8960_RINPATH_RMP2_SET(x) (((uint16_t)(x) << WM8960_RINPATH_RMP2_SHIFT) & WM8960_RINPATH_RMP2_MASK) +#define WM8960_RINPATH_RMP2_GET(x) (((uint16_t)(x) & WM8960_RINPATH_RMP2_MASK) >> WM8960_RINPATH_RMP2_SHIFT) + +/* + * RMICBOOST (RW) + * + * Right Channel Input PGA Boost Gain + * 00 = +0dB + * 01 = +13dB + * 10 = +20dB + * 11 = +29dB + */ +#define WM8960_RINPATH_RMICBOOST_MASK (0x30U) +#define WM8960_RINPATH_RMICBOOST_SHIFT (4U) +#define WM8960_RINPATH_RMICBOOST_SET(x) (((uint16_t)(x) << WM8960_RINPATH_RMICBOOST_SHIFT) & WM8960_RINPATH_RMICBOOST_MASK) +#define WM8960_RINPATH_RMICBOOST_GET(x) (((uint16_t)(x) & WM8960_RINPATH_RMICBOOST_MASK) >> WM8960_RINPATH_RMICBOOST_SHIFT) + +/* + * RMIC2B (RW) + * + * Connect Right Input PGA to Right Input Boost + * Mixer + * 0 = Not connected + * 1 = Connected + */ +#define WM8960_RINPATH_RMIC2B_MASK (0x8U) +#define WM8960_RINPATH_RMIC2B_SHIFT (3U) +#define WM8960_RINPATH_RMIC2B_SET(x) (((uint16_t)(x) << WM8960_RINPATH_RMIC2B_SHIFT) & WM8960_RINPATH_RMIC2B_MASK) +#define WM8960_RINPATH_RMIC2B_GET(x) (((uint16_t)(x) & WM8960_RINPATH_RMIC2B_MASK) >> WM8960_RINPATH_RMIC2B_SHIFT) + +/* Bitfield definition for register: LOUTMIX */ +/* + * LD2LO (RW) + * + * Left DAC to Left Output Mixer + * 0 = Disable (Mute) + * 1 = Enable Path + */ +#define WM8960_LOUTMIX_LD2LO_MASK (0x100U) +#define WM8960_LOUTMIX_LD2LO_SHIFT (8U) +#define WM8960_LOUTMIX_LD2LO_SET(x) (((uint16_t)(x) << WM8960_LOUTMIX_LD2LO_SHIFT) & WM8960_LOUTMIX_LD2LO_MASK) +#define WM8960_LOUTMIX_LD2LO_GET(x) (((uint16_t)(x) & WM8960_LOUTMIX_LD2LO_MASK) >> WM8960_LOUTMIX_LD2LO_SHIFT) + +/* + * LI2LO (RW) + * + * LINPUT3 to Left Output Mixer + * 0 = Disable (Mute) + * 1 = Enable Path + */ +#define WM8960_LOUTMIX_LI2LO_MASK (0x80U) +#define WM8960_LOUTMIX_LI2LO_SHIFT (7U) +#define WM8960_LOUTMIX_LI2LO_SET(x) (((uint16_t)(x) << WM8960_LOUTMIX_LI2LO_SHIFT) & WM8960_LOUTMIX_LI2LO_MASK) +#define WM8960_LOUTMIX_LI2LO_GET(x) (((uint16_t)(x) & WM8960_LOUTMIX_LI2LO_MASK) >> WM8960_LOUTMIX_LI2LO_SHIFT) + +/* + * LI2LOVOL (RW) + * + * LINPUT3 to Left Output Mixer Volume + * 000 = 0dB + * ...(3dB steps) + * 111 = -21dB + */ +#define WM8960_LOUTMIX_LI2LOVOL_MASK (0x70U) +#define WM8960_LOUTMIX_LI2LOVOL_SHIFT (4U) +#define WM8960_LOUTMIX_LI2LOVOL_SET(x) (((uint16_t)(x) << WM8960_LOUTMIX_LI2LOVOL_SHIFT) & WM8960_LOUTMIX_LI2LOVOL_MASK) +#define WM8960_LOUTMIX_LI2LOVOL_GET(x) (((uint16_t)(x) & WM8960_LOUTMIX_LI2LOVOL_MASK) >> WM8960_LOUTMIX_LI2LOVOL_SHIFT) + +/* Bitfield definition for register: ROUTMIX */ +/* + * RD2RO (RW) + * + * Right DAC to Right Output Mixer + * 0 = Disable (Mute) + * 1 = Enable Path + */ +#define WM8960_ROUTMIX_RD2RO_MASK (0x100U) +#define WM8960_ROUTMIX_RD2RO_SHIFT (8U) +#define WM8960_ROUTMIX_RD2RO_SET(x) (((uint16_t)(x) << WM8960_ROUTMIX_RD2RO_SHIFT) & WM8960_ROUTMIX_RD2RO_MASK) +#define WM8960_ROUTMIX_RD2RO_GET(x) (((uint16_t)(x) & WM8960_ROUTMIX_RD2RO_MASK) >> WM8960_ROUTMIX_RD2RO_SHIFT) + +/* + * RI2RO (RW) + * + * RINPUT3 to Right Output Mixer + * 0 = Disable (Mute) + * 1 = Enable Path + */ +#define WM8960_ROUTMIX_RI2RO_MASK (0x80U) +#define WM8960_ROUTMIX_RI2RO_SHIFT (7U) +#define WM8960_ROUTMIX_RI2RO_SET(x) (((uint16_t)(x) << WM8960_ROUTMIX_RI2RO_SHIFT) & WM8960_ROUTMIX_RI2RO_MASK) +#define WM8960_ROUTMIX_RI2RO_GET(x) (((uint16_t)(x) & WM8960_ROUTMIX_RI2RO_MASK) >> WM8960_ROUTMIX_RI2RO_SHIFT) + +/* + * RI2ROVOL (RW) + * + * RINPUT3 to Right Output Mixer Volume + * 000 = 0dB + * ...(3dB steps) + * 111 = -21dB + */ +#define WM8960_ROUTMIX_RI2ROVOL_MASK (0x70U) +#define WM8960_ROUTMIX_RI2ROVOL_SHIFT (4U) +#define WM8960_ROUTMIX_RI2ROVOL_SET(x) (((uint16_t)(x) << WM8960_ROUTMIX_RI2ROVOL_SHIFT) & WM8960_ROUTMIX_RI2ROVOL_MASK) +#define WM8960_ROUTMIX_RI2ROVOL_GET(x) (((uint16_t)(x) & WM8960_ROUTMIX_RI2ROVOL_MASK) >> WM8960_ROUTMIX_RI2ROVOL_SHIFT) + +/* Bitfield definition for register: MONOMIX1 */ +/* + * L2MO (RW) + * + * Left Output Mixer to Mono Output Mixer Control + * 0 = Left channel mix disabled + * 1 = Left channel mix enabled + */ +#define WM8960_MONOMIX1_L2MO_MASK (0x80U) +#define WM8960_MONOMIX1_L2MO_SHIFT (7U) +#define WM8960_MONOMIX1_L2MO_SET(x) (((uint16_t)(x) << WM8960_MONOMIX1_L2MO_SHIFT) & WM8960_MONOMIX1_L2MO_MASK) +#define WM8960_MONOMIX1_L2MO_GET(x) (((uint16_t)(x) & WM8960_MONOMIX1_L2MO_MASK) >> WM8960_MONOMIX1_L2MO_SHIFT) + +/* Bitfield definition for register: MONOMIX2 */ +/* + * R2MO (RW) + * + * Right Output Mixer to Mono Output Mixer Control + * 0 = Right channel mix disabled + * 1 = Right channel mix enabled + */ +#define WM8960_MONOMIX2_R2MO_MASK (0x80U) +#define WM8960_MONOMIX2_R2MO_SHIFT (7U) +#define WM8960_MONOMIX2_R2MO_SET(x) (((uint16_t)(x) << WM8960_MONOMIX2_R2MO_SHIFT) & WM8960_MONOMIX2_R2MO_MASK) +#define WM8960_MONOMIX2_R2MO_GET(x) (((uint16_t)(x) & WM8960_MONOMIX2_R2MO_MASK) >> WM8960_MONOMIX2_R2MO_SHIFT) + +/* Bitfield definition for register: LOUT2 */ +/* + * SPKVU (RW) + * + * Speaker Volume Update + * Writing a 1 to this bit will cause left and right speaker volumes to be updated (SPKLVOL and SPKRVOL) + */ +#define WM8960_LOUT2_SPKVU_MASK (0x100U) +#define WM8960_LOUT2_SPKVU_SHIFT (8U) +#define WM8960_LOUT2_SPKVU_SET(x) (((uint16_t)(x) << WM8960_LOUT2_SPKVU_SHIFT) & WM8960_LOUT2_SPKVU_MASK) +#define WM8960_LOUT2_SPKVU_GET(x) (((uint16_t)(x) & WM8960_LOUT2_SPKVU_MASK) >> WM8960_LOUT2_SPKVU_SHIFT) + +/* + * SPKLZC (RW) + * + * Left Speaker Zero Cross Enable + * 1 = Change gain on zero cross only + * 0 = Change gain immediately + */ +#define WM8960_LOUT2_SPKLZC_MASK (0x80U) +#define WM8960_LOUT2_SPKLZC_SHIFT (7U) +#define WM8960_LOUT2_SPKLZC_SET(x) (((uint16_t)(x) << WM8960_LOUT2_SPKLZC_SHIFT) & WM8960_LOUT2_SPKLZC_MASK) +#define WM8960_LOUT2_SPKLZC_GET(x) (((uint16_t)(x) & WM8960_LOUT2_SPKLZC_MASK) >> WM8960_LOUT2_SPKLZC_SHIFT) + +/* + * SPKLVOL (RW) + * + * SPK_LP/SPK_LN Volume + * 1111111 = +6dB + * … 1dB steps down to + * 0110000 = -73dB + * 0101111 to 0000000 = Analogue MUTE + */ +#define WM8960_LOUT2_SPKLVOL_MASK (0x7FU) +#define WM8960_LOUT2_SPKLVOL_SHIFT (0U) +#define WM8960_LOUT2_SPKLVOL_SET(x) (((uint16_t)(x) << WM8960_LOUT2_SPKLVOL_SHIFT) & WM8960_LOUT2_SPKLVOL_MASK) +#define WM8960_LOUT2_SPKLVOL_GET(x) (((uint16_t)(x) & WM8960_LOUT2_SPKLVOL_MASK) >> WM8960_LOUT2_SPKLVOL_SHIFT) + +/* Bitfield definition for register: ROUT2 */ +/* + * SPKVU (RW) + * + * Speaker Volume Update + * Writing a 1 to this bit will cause left and right + * speaker volumes to be updated (SPKLVOL and SPKRVOL) + */ +#define WM8960_ROUT2_SPKVU_MASK (0x100U) +#define WM8960_ROUT2_SPKVU_SHIFT (8U) +#define WM8960_ROUT2_SPKVU_SET(x) (((uint16_t)(x) << WM8960_ROUT2_SPKVU_SHIFT) & WM8960_ROUT2_SPKVU_MASK) +#define WM8960_ROUT2_SPKVU_GET(x) (((uint16_t)(x) & WM8960_ROUT2_SPKVU_MASK) >> WM8960_ROUT2_SPKVU_SHIFT) + +/* + * SPKRZC (RW) + * + * Right Speaker Zero Cross Enable + * 1 = Change gain on zero cross only + * 0 = Change gain immediately + */ +#define WM8960_ROUT2_SPKRZC_MASK (0x80U) +#define WM8960_ROUT2_SPKRZC_SHIFT (7U) +#define WM8960_ROUT2_SPKRZC_SET(x) (((uint16_t)(x) << WM8960_ROUT2_SPKRZC_SHIFT) & WM8960_ROUT2_SPKRZC_MASK) +#define WM8960_ROUT2_SPKRZC_GET(x) (((uint16_t)(x) & WM8960_ROUT2_SPKRZC_MASK) >> WM8960_ROUT2_SPKRZC_SHIFT) + +/* + * SPKRVOL (RW) + * + * SPK_RP/SPK_RN Volume + * 1111111 = +6dB + * … 1dB steps down to + * 0110000 = -73dB + * 0101111 to 0000000 = Analogue MUTE + */ +#define WM8960_ROUT2_SPKRVOL_MASK (0x7FU) +#define WM8960_ROUT2_SPKRVOL_SHIFT (0U) +#define WM8960_ROUT2_SPKRVOL_SET(x) (((uint16_t)(x) << WM8960_ROUT2_SPKRVOL_SHIFT) & WM8960_ROUT2_SPKRVOL_MASK) +#define WM8960_ROUT2_SPKRVOL_GET(x) (((uint16_t)(x) & WM8960_ROUT2_SPKRVOL_MASK) >> WM8960_ROUT2_SPKRVOL_SHIFT) + +/* Bitfield definition for register: MONO */ +/* + * MOUTVOL (RW) + * + * Mono Output Mixer Volume Control + * 0 = 0dB + * 1 = -6dB + */ +#define WM8960_MONO_MOUTVOL_MASK (0x40U) +#define WM8960_MONO_MOUTVOL_SHIFT (6U) +#define WM8960_MONO_MOUTVOL_SET(x) (((uint16_t)(x) << WM8960_MONO_MOUTVOL_SHIFT) & WM8960_MONO_MOUTVOL_MASK) +#define WM8960_MONO_MOUTVOL_GET(x) (((uint16_t)(x) & WM8960_MONO_MOUTVOL_MASK) >> WM8960_MONO_MOUTVOL_SHIFT) + +/* Bitfield definition for register: INBMIX1 */ +/* + * LIN3BOOST (RW) + * + * LINPUT3 to Boost Mixer Gain + * 000 = Mute + * 001 = -12dB + * ...3dB steps up to + * 111 = +6dB + */ +#define WM8960_INBMIX1_LIN3BOOST_MASK (0x70U) +#define WM8960_INBMIX1_LIN3BOOST_SHIFT (4U) +#define WM8960_INBMIX1_LIN3BOOST_SET(x) (((uint16_t)(x) << WM8960_INBMIX1_LIN3BOOST_SHIFT) & WM8960_INBMIX1_LIN3BOOST_MASK) +#define WM8960_INBMIX1_LIN3BOOST_GET(x) (((uint16_t)(x) & WM8960_INBMIX1_LIN3BOOST_MASK) >> WM8960_INBMIX1_LIN3BOOST_SHIFT) + +/* + * LIN2BOOST (RW) + * + * LINPUT2 to Boost Mixer Gain + * 000 = Mute + * 001 = -12dB + * ...3dB steps up to + * 111 = +6dB + */ +#define WM8960_INBMIX1_LIN2BOOST_MASK (0xEU) +#define WM8960_INBMIX1_LIN2BOOST_SHIFT (1U) +#define WM8960_INBMIX1_LIN2BOOST_SET(x) (((uint16_t)(x) << WM8960_INBMIX1_LIN2BOOST_SHIFT) & WM8960_INBMIX1_LIN2BOOST_MASK) +#define WM8960_INBMIX1_LIN2BOOST_GET(x) (((uint16_t)(x) & WM8960_INBMIX1_LIN2BOOST_MASK) >> WM8960_INBMIX1_LIN2BOOST_SHIFT) + +/* Bitfield definition for register: INBMIX2 */ +/* + * RIN3BOOST (RW) + * + * RINPUT3 to Boost Mixer Gain + * 000 = Mute + * 001 = -12dB + * ...3dB steps up to + * 111 = +6dB + */ +#define WM8960_INBMIX2_RIN3BOOST_MASK (0x70U) +#define WM8960_INBMIX2_RIN3BOOST_SHIFT (4U) +#define WM8960_INBMIX2_RIN3BOOST_SET(x) (((uint16_t)(x) << WM8960_INBMIX2_RIN3BOOST_SHIFT) & WM8960_INBMIX2_RIN3BOOST_MASK) +#define WM8960_INBMIX2_RIN3BOOST_GET(x) (((uint16_t)(x) & WM8960_INBMIX2_RIN3BOOST_MASK) >> WM8960_INBMIX2_RIN3BOOST_SHIFT) + +/* + * RIN2BOOST (RW) + * + * RINPUT2 to Boost Mixer Gain + * 000 = Mute + * 001 = -12dB + * ...3dB steps up to + * 111 = +6dB + */ +#define WM8960_INBMIX2_RIN2BOOST_MASK (0xEU) +#define WM8960_INBMIX2_RIN2BOOST_SHIFT (1U) +#define WM8960_INBMIX2_RIN2BOOST_SET(x) (((uint16_t)(x) << WM8960_INBMIX2_RIN2BOOST_SHIFT) & WM8960_INBMIX2_RIN2BOOST_MASK) +#define WM8960_INBMIX2_RIN2BOOST_GET(x) (((uint16_t)(x) & WM8960_INBMIX2_RIN2BOOST_MASK) >> WM8960_INBMIX2_RIN2BOOST_SHIFT) + +/* Bitfield definition for register: BYPASS1 */ +/* + * LB2LO (RW) + * + * Left Input Boost Mixer to Left Output Mixer + * 0 = Disable (Mute) + * 1 = Enable Path + */ +#define WM8960_BYPASS1_LB2LO_MASK (0x80U) +#define WM8960_BYPASS1_LB2LO_SHIFT (7U) +#define WM8960_BYPASS1_LB2LO_SET(x) (((uint16_t)(x) << WM8960_BYPASS1_LB2LO_SHIFT) & WM8960_BYPASS1_LB2LO_MASK) +#define WM8960_BYPASS1_LB2LO_GET(x) (((uint16_t)(x) & WM8960_BYPASS1_LB2LO_MASK) >> WM8960_BYPASS1_LB2LO_SHIFT) + +/* + * LB2LOVOL (RW) + * + * Left Input Boost Mixer to Left Output Mixer + * Volume + * 000 = 0dB + * ...(3dB steps) + * 111 = -21dB + */ +#define WM8960_BYPASS1_LB2LOVOL_MASK (0x70U) +#define WM8960_BYPASS1_LB2LOVOL_SHIFT (4U) +#define WM8960_BYPASS1_LB2LOVOL_SET(x) (((uint16_t)(x) << WM8960_BYPASS1_LB2LOVOL_SHIFT) & WM8960_BYPASS1_LB2LOVOL_MASK) +#define WM8960_BYPASS1_LB2LOVOL_GET(x) (((uint16_t)(x) & WM8960_BYPASS1_LB2LOVOL_MASK) >> WM8960_BYPASS1_LB2LOVOL_SHIFT) + +/* Bitfield definition for register: BYPASS2 */ +/* + * RB2RO (RW) + * + * Right Input Boost Mixer to Right Output Mixer + * 0 = Disable (Mute) + * 1 = Enable Path + */ +#define WM8960_BYPASS2_RB2RO_MASK (0x80U) +#define WM8960_BYPASS2_RB2RO_SHIFT (7U) +#define WM8960_BYPASS2_RB2RO_SET(x) (((uint16_t)(x) << WM8960_BYPASS2_RB2RO_SHIFT) & WM8960_BYPASS2_RB2RO_MASK) +#define WM8960_BYPASS2_RB2RO_GET(x) (((uint16_t)(x) & WM8960_BYPASS2_RB2RO_MASK) >> WM8960_BYPASS2_RB2RO_SHIFT) + +/* + * RB2ROVOL (RW) + * + * Right Input Boost Mixer to Right Output Mixer + * Volume + * 000 = 0dB + * ...(3dB steps) + * 111 = -21dB + */ +#define WM8960_BYPASS2_RB2ROVOL_MASK (0x70U) +#define WM8960_BYPASS2_RB2ROVOL_SHIFT (4U) +#define WM8960_BYPASS2_RB2ROVOL_SET(x) (((uint16_t)(x) << WM8960_BYPASS2_RB2ROVOL_SHIFT) & WM8960_BYPASS2_RB2ROVOL_MASK) +#define WM8960_BYPASS2_RB2ROVOL_GET(x) (((uint16_t)(x) & WM8960_BYPASS2_RB2ROVOL_MASK) >> WM8960_BYPASS2_RB2ROVOL_SHIFT) + +/* Bitfield definition for register: POWER3 */ +/* + * LMIC (RW) + * + * Left Channel Input PGA Enable + * 0 = PGA disabled + * 1 = PGA enabled (if AINL = 1) + */ +#define WM8960_POWER3_LMIC_MASK (0x20U) +#define WM8960_POWER3_LMIC_SHIFT (5U) +#define WM8960_POWER3_LMIC_SET(x) (((uint16_t)(x) << WM8960_POWER3_LMIC_SHIFT) & WM8960_POWER3_LMIC_MASK) +#define WM8960_POWER3_LMIC_GET(x) (((uint16_t)(x) & WM8960_POWER3_LMIC_MASK) >> WM8960_POWER3_LMIC_SHIFT) + +/* + * RMIC (RW) + * + * Right Channel Input PGA Enable + * 0 = PGA disabled + * 1 = PGA enabled (if AINR = 1) + */ +#define WM8960_POWER3_RMIC_MASK (0x10U) +#define WM8960_POWER3_RMIC_SHIFT (4U) +#define WM8960_POWER3_RMIC_SET(x) (((uint16_t)(x) << WM8960_POWER3_RMIC_SHIFT) & WM8960_POWER3_RMIC_MASK) +#define WM8960_POWER3_RMIC_GET(x) (((uint16_t)(x) & WM8960_POWER3_RMIC_MASK) >> WM8960_POWER3_RMIC_SHIFT) + +/* + * LOMIX (RW) + * + * Left Output Mixer Enable Control + * 0 = Disabled + * 1 = Enabled + */ +#define WM8960_POWER3_LOMIX_MASK (0x8U) +#define WM8960_POWER3_LOMIX_SHIFT (3U) +#define WM8960_POWER3_LOMIX_SET(x) (((uint16_t)(x) << WM8960_POWER3_LOMIX_SHIFT) & WM8960_POWER3_LOMIX_MASK) +#define WM8960_POWER3_LOMIX_GET(x) (((uint16_t)(x) & WM8960_POWER3_LOMIX_MASK) >> WM8960_POWER3_LOMIX_SHIFT) + +/* + * ROMIX (RW) + * + * Right Output Mixer Enable Control + * 0 = Disabled + * 1 = Enabled + */ +#define WM8960_POWER3_ROMIX_MASK (0x4U) +#define WM8960_POWER3_ROMIX_SHIFT (2U) +#define WM8960_POWER3_ROMIX_SET(x) (((uint16_t)(x) << WM8960_POWER3_ROMIX_SHIFT) & WM8960_POWER3_ROMIX_MASK) +#define WM8960_POWER3_ROMIX_GET(x) (((uint16_t)(x) & WM8960_POWER3_ROMIX_MASK) >> WM8960_POWER3_ROMIX_SHIFT) + +/* Bitfield definition for register: ADDCTL4 */ +/* + * GPIOPOL (RW) + * + * GPIO Polarity Invert + * 0 = Non inverted + * 1 = Inverted + */ +#define WM8960_ADDCTL4_GPIOPOL_MASK (0x80U) +#define WM8960_ADDCTL4_GPIOPOL_SHIFT (7U) +#define WM8960_ADDCTL4_GPIOPOL_SET(x) (((uint16_t)(x) << WM8960_ADDCTL4_GPIOPOL_SHIFT) & WM8960_ADDCTL4_GPIOPOL_MASK) +#define WM8960_ADDCTL4_GPIOPOL_GET(x) (((uint16_t)(x) & WM8960_ADDCTL4_GPIOPOL_MASK) >> WM8960_ADDCTL4_GPIOPOL_SHIFT) + +/* + * GPIOSEL (RW) + * + * ADCLRC/GPIO1 GPIO Function Select: + * 000 = Jack detect input + * 001 = Reserved + * 010 = Temperature ok + * 011 = Debounced jack detect output + * 100 = SYSCLK output + * 101 = PLL lock + * 110 = Logic 0 + * 111 = Logic 1 + */ +#define WM8960_ADDCTL4_GPIOSEL_MASK (0x70U) +#define WM8960_ADDCTL4_GPIOSEL_SHIFT (4U) +#define WM8960_ADDCTL4_GPIOSEL_SET(x) (((uint16_t)(x) << WM8960_ADDCTL4_GPIOSEL_SHIFT) & WM8960_ADDCTL4_GPIOSEL_MASK) +#define WM8960_ADDCTL4_GPIOSEL_GET(x) (((uint16_t)(x) & WM8960_ADDCTL4_GPIOSEL_MASK) >> WM8960_ADDCTL4_GPIOSEL_SHIFT) + +/* + * HPSEL (RW) + * + * Headphone Switch Input Select + * 0X = GPIO1 used for jack detect input (Requires + * ADCLRC pin to be configured as a GPIO) + * 10 = JD2 used for jack detect input + * 11 = JD3 used for jack detect input + */ +#define WM8960_ADDCTL4_HPSEL_MASK (0xCU) +#define WM8960_ADDCTL4_HPSEL_SHIFT (2U) +#define WM8960_ADDCTL4_HPSEL_SET(x) (((uint16_t)(x) << WM8960_ADDCTL4_HPSEL_SHIFT) & WM8960_ADDCTL4_HPSEL_MASK) +#define WM8960_ADDCTL4_HPSEL_GET(x) (((uint16_t)(x) & WM8960_ADDCTL4_HPSEL_MASK) >> WM8960_ADDCTL4_HPSEL_SHIFT) + +/* + * TSENSEN (RW) + * + * Temperature Sensor Enable + * 0 = Temperature sensor disabled + * 1 = Temperature sensor enabled + */ +#define WM8960_ADDCTL4_TSENSEN_MASK (0x2U) +#define WM8960_ADDCTL4_TSENSEN_SHIFT (1U) +#define WM8960_ADDCTL4_TSENSEN_SET(x) (((uint16_t)(x) << WM8960_ADDCTL4_TSENSEN_SHIFT) & WM8960_ADDCTL4_TSENSEN_MASK) +#define WM8960_ADDCTL4_TSENSEN_GET(x) (((uint16_t)(x) & WM8960_ADDCTL4_TSENSEN_MASK) >> WM8960_ADDCTL4_TSENSEN_SHIFT) + +/* + * MBSEL (RW) + * + * Microphone Bias Voltage Control + * 0 = 0.9 * AVDD + * 1 = 0.65 * AVDD + */ +#define WM8960_ADDCTL4_MBSEL_MASK (0x1U) +#define WM8960_ADDCTL4_MBSEL_SHIFT (0U) +#define WM8960_ADDCTL4_MBSEL_SET(x) (((uint16_t)(x) << WM8960_ADDCTL4_MBSEL_SHIFT) & WM8960_ADDCTL4_MBSEL_MASK) +#define WM8960_ADDCTL4_MBSEL_GET(x) (((uint16_t)(x) & WM8960_ADDCTL4_MBSEL_MASK) >> WM8960_ADDCTL4_MBSEL_SHIFT) + +/* Bitfield definition for register: CLASSD1 */ +/* + * SPK_OP_EN (RW) + * + * Enable Class D Speaker Outputs + * 00 = Off + * 01 = Left speaker only + * 10 = Right speaker only + * 11 = Left and right speakers enabled + */ +#define WM8960_CLASSD1_SPK_OP_EN_MASK (0xC0U) +#define WM8960_CLASSD1_SPK_OP_EN_SHIFT (6U) +#define WM8960_CLASSD1_SPK_OP_EN_SET(x) (((uint16_t)(x) << WM8960_CLASSD1_SPK_OP_EN_SHIFT) & WM8960_CLASSD1_SPK_OP_EN_MASK) +#define WM8960_CLASSD1_SPK_OP_EN_GET(x) (((uint16_t)(x) & WM8960_CLASSD1_SPK_OP_EN_MASK) >> WM8960_CLASSD1_SPK_OP_EN_SHIFT) + +/* Bitfield definition for register: CLASSD3 */ +/* + * DCGAIN (RW) + * + * DC Speaker Boost (Boosts speaker DC output + * level by up to 1.8 x on left and right channels) + * 000 = 1.00x boost (+0dB) + * 001 = 1.27x boost (+2.1dB) + * 010 = 1.40x boost (+2.9dB) + * 011 = 1.52x boost (+3.6dB) + * 100 = 1.67x boost (+4.5dB) + * 101 = 1.8x boost (+5.1dB) + * 110 to 111 = Reserved + */ +#define WM8960_CLASSD3_DCGAIN_MASK (0x38U) +#define WM8960_CLASSD3_DCGAIN_SHIFT (3U) +#define WM8960_CLASSD3_DCGAIN_SET(x) (((uint16_t)(x) << WM8960_CLASSD3_DCGAIN_SHIFT) & WM8960_CLASSD3_DCGAIN_MASK) +#define WM8960_CLASSD3_DCGAIN_GET(x) (((uint16_t)(x) & WM8960_CLASSD3_DCGAIN_MASK) >> WM8960_CLASSD3_DCGAIN_SHIFT) + +/* + * ACGAIN (RW) + * + * AC Speaker Boost (Boosts speaker AC output + * signal by up to 1.8 x on left and right channels) + * 000 = 1.00x boost (+0dB) + * 001 = 1.27x boost (+2.1dB) + * 010 = 1.40x boost (+2.9dB) + * 011 = 1.52x boost (+3.6dB) + * 100 = 1.67x boost (+4.5dB) + * 101 = 1.8x boost (+5.1dB) + * 110 to 111 = Reserved + */ +#define WM8960_CLASSD3_ACGAIN_MASK (0x7U) +#define WM8960_CLASSD3_ACGAIN_SHIFT (0U) +#define WM8960_CLASSD3_ACGAIN_SET(x) (((uint16_t)(x) << WM8960_CLASSD3_ACGAIN_SHIFT) & WM8960_CLASSD3_ACGAIN_MASK) +#define WM8960_CLASSD3_ACGAIN_GET(x) (((uint16_t)(x) & WM8960_CLASSD3_ACGAIN_MASK) >> WM8960_CLASSD3_ACGAIN_SHIFT) + +/* Bitfield definition for register: PLL1 */ +/* + * OPCLKDIV (RW) + * + * SYSCLK Output to GPIO Clock Division ratio + * 000 = SYSCLK + * 001 = SYSCLK / 2 + * 010 = SYSCLK / 3 + * 011 = SYSCLK / 4 + * 100 = SYSCLK / 5.5 + * 101 = SYSCLK / 6 + */ +#define WM8960_PLL1_OPCLKDIV_MASK (0x1C0U) +#define WM8960_PLL1_OPCLKDIV_SHIFT (6U) +#define WM8960_PLL1_OPCLKDIV_SET(x) (((uint16_t)(x) << WM8960_PLL1_OPCLKDIV_SHIFT) & WM8960_PLL1_OPCLKDIV_MASK) +#define WM8960_PLL1_OPCLKDIV_GET(x) (((uint16_t)(x) & WM8960_PLL1_OPCLKDIV_MASK) >> WM8960_PLL1_OPCLKDIV_SHIFT) + +/* + * SDM (RW) + * + * Enable Integer Mode + * 0 = Integer mode + * 1 = Fractional mode + */ +#define WM8960_PLL1_SDM_MASK (0x20U) +#define WM8960_PLL1_SDM_SHIFT (5U) +#define WM8960_PLL1_SDM_SET(x) (((uint16_t)(x) << WM8960_PLL1_SDM_SHIFT) & WM8960_PLL1_SDM_MASK) +#define WM8960_PLL1_SDM_GET(x) (((uint16_t)(x) & WM8960_PLL1_SDM_MASK) >> WM8960_PLL1_SDM_SHIFT) + +/* + * PLLPRESCALE (RW) + * + * Divide MCLK by 2 before input to PLL + * 0 = Divide by 1 + * 1 = Divide by 2 + */ +#define WM8960_PLL1_PLLPRESCALE_MASK (0x10U) +#define WM8960_PLL1_PLLPRESCALE_SHIFT (4U) +#define WM8960_PLL1_PLLPRESCALE_SET(x) (((uint16_t)(x) << WM8960_PLL1_PLLPRESCALE_SHIFT) & WM8960_PLL1_PLLPRESCALE_MASK) +#define WM8960_PLL1_PLLPRESCALE_GET(x) (((uint16_t)(x) & WM8960_PLL1_PLLPRESCALE_MASK) >> WM8960_PLL1_PLLPRESCALE_SHIFT) + +/* + * PLLN (RW) + * + * Integer (N) part of PLL input/output frequency + * ratio. Use values greater than 5 and less than 13 + */ +#define WM8960_PLL1_PLLN_MASK (0xFU) +#define WM8960_PLL1_PLLN_SHIFT (0U) +#define WM8960_PLL1_PLLN_SET(x) (((uint16_t)(x) << WM8960_PLL1_PLLN_SHIFT) & WM8960_PLL1_PLLN_MASK) +#define WM8960_PLL1_PLLN_GET(x) (((uint16_t)(x) & WM8960_PLL1_PLLN_MASK) >> WM8960_PLL1_PLLN_SHIFT) + +/* Bitfield definition for register: PLL2 */ +/* + * PLLK (RW) + * + * Fractional (K) part of PLL1 input/output + * frequency ratio (treat as one 24-digit binary number). + */ +#define WM8960_PLL2_PLLK_MASK (0xFFU) +#define WM8960_PLL2_PLLK_SHIFT (0U) +#define WM8960_PLL2_PLLK_SET(x) (((uint16_t)(x) << WM8960_PLL2_PLLK_SHIFT) & WM8960_PLL2_PLLK_MASK) +#define WM8960_PLL2_PLLK_GET(x) (((uint16_t)(x) & WM8960_PLL2_PLLK_MASK) >> WM8960_PLL2_PLLK_SHIFT) + +/* Bitfield definition for register: PLL3 */ +/* + * PLLK (RW) + * + * Fractional (K) part of PLL1 input/output + * frequency ratio (treat as one 24-digit binary number). + */ +#define WM8960_PLL3_PLLK_MASK (0xFFU) +#define WM8960_PLL3_PLLK_SHIFT (0U) +#define WM8960_PLL3_PLLK_SET(x) (((uint16_t)(x) << WM8960_PLL3_PLLK_SHIFT) & WM8960_PLL3_PLLK_MASK) +#define WM8960_PLL3_PLLK_GET(x) (((uint16_t)(x) & WM8960_PLL3_PLLK_MASK) >> WM8960_PLL3_PLLK_SHIFT) + +/* Bitfield definition for register: PLL4 */ +/* + * PLLK (RW) + * + * Fractional (K) part of PLL1 input/output + * frequency ratio (treat as one 24-digit binary number). + */ +#define WM8960_PLL4_PLLK_MASK (0xFFU) +#define WM8960_PLL4_PLLK_SHIFT (0U) +#define WM8960_PLL4_PLLK_SET(x) (((uint16_t)(x) << WM8960_PLL4_PLLK_SHIFT) & WM8960_PLL4_PLLK_MASK) +#define WM8960_PLL4_PLLK_GET(x) (((uint16_t)(x) & WM8960_PLL4_PLLK_MASK) >> WM8960_PLL4_PLLK_SHIFT) + + +#endif /* _HPM_WM8960_REG_H_ */ diff --git a/bsp/hpmicro/hpm6e00evk/board/linker_scripts/flash_rtt.ld b/bsp/hpmicro/hpm6e00evk/board/linker_scripts/flash_rtt.ld new file mode 100644 index 0000000000..16d433aa93 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/linker_scripts/flash_rtt.ld @@ -0,0 +1,297 @@ +/* + * Copyright 2021-2024 HPMicro + * SPDX-License-Identifier: BSD-3-Clause + */ + +ENTRY(_start) + +STACK_SIZE = DEFINED(_stack_size) ? _stack_size : 0x4000; +HEAP_SIZE = DEFINED(_heap_size) ? _heap_size : 128K; +FLASH_SIZE = DEFINED(_flash_size) ? _flash_size : 16M; +NONCACHEABLE_SIZE = DEFINED(_noncacheable_size) ? _noncacheable_size : 512K; + +MEMORY +{ + XPI0 (rx) : ORIGIN = 0x80000000, LENGTH = FLASH_SIZE + ILM (wx) : ORIGIN = 0, LENGTH = 256K + DLM (w) : ORIGIN = 0x00200000, LENGTH = 256K + AXI_SRAM (wx) : ORIGIN = 0x01200000, LENGTH = 512K + NONCACHEABLE_RAM (wx) : ORIGIN = 0x01280000, LENGTH = NONCACHEABLE_SIZE + AHB_SRAM (w): ORIGIN = 0xF0200000, LENGTH = 32k +} + +__nor_cfg_option_load_addr__ = ORIGIN(XPI0) + 0x400; +__boot_header_load_addr__ = ORIGIN(XPI0) + 0x1000; +__app_load_addr__ = ORIGIN(XPI0) + 0x3000; +__boot_header_length__ = __boot_header_end__ - __boot_header_start__; +__app_offset__ = __app_load_addr__ - __boot_header_load_addr__; + +SECTIONS +{ + .nor_cfg_option __nor_cfg_option_load_addr__ : { + KEEP(*(.nor_cfg_option)) + } > XPI0 + + .boot_header __boot_header_load_addr__ : { + __boot_header_start__ = .; + KEEP(*(.boot_header)) + KEEP(*(.fw_info_table)) + KEEP(*(.dc_info)) + __boot_header_end__ = .; + } > XPI0 + + .start __app_load_addr__ : { + . = ALIGN(8); + KEEP(*(.start)) + } > XPI0 + + __vector_load_addr__ = ADDR(.start) + SIZEOF(.start); + .vectors : AT(__vector_load_addr__) { + . = ALIGN(8); + __vector_ram_start__ = .; + KEEP(*(.vector_table)) + KEEP(*(.isr_vector)) + + . = ALIGN(8); + __vector_ram_end__ = .; + } > ILM + + .fast : AT(etext + __data_end__ - __tdata_start__) { + . = ALIGN(8); + __ramfunc_start__ = .; + *(.fast) + + /* RT-Thread Core Start */ + KEEP(*context_gcc.o(.text* .rodata*)) + KEEP(*port*.o (.text .text* .rodata .rodata*)) + KEEP(*interrupt_gcc.o (.text .text* .rodata .rodata*)) + KEEP(*trap_common.o (.text .text* .rodata .rodata*)) + KEEP(*irq.o (.text .text* .rodata .rodata*)) + KEEP(*clock.o (.text .text* .rodata .rodata*)) + KEEP(*kservice.o (.text .text* .rodata .rodata*)) + KEEP(*scheduler.o (.text .text* .rodata .rodata*)) + KEEP(*trap*.o (.text .text* .rodata .rodata*)) + KEEP(*idle.o (.text .text* .rodata .rodata*)) + KEEP(*ipc.o (.text .text* .rodata .rodata*)) + KEEP(*thread.o (.text .text* .rodata .rodata*)) + KEEP(*object.o (.text .text* .rodata .rodata*)) + KEEP(*timer.o (.text .text* .rodata .rodata*)) + KEEP(*mem.o (.text .text* .rodata .rodata*)) + KEEP(*mempool.o (.text .text* .rodata .rodata*)) + /* RT-Thread Core End */ + + /* HPMicro Driver Wrapper */ + KEEP(*drv_*.o (.text .text* .rodata .rodata*)) + + . = ALIGN(8); + __ramfunc_end__ = .; + } > ILM + + .text (__vector_load_addr__ + __vector_ram_end__ - __vector_ram_start__) : { + . = ALIGN(8); + *(.text) + *(.text*) + *(.rodata) + *(.rodata*) + *(.srodata) + *(.srodata*) + + *(.hash) + *(.dyn*) + *(.gnu*) + *(.pl*) + + KEEP(*(.eh_frame)) + *(.eh_frame*) + + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(8); + + /********************************************* + * + * RT-Thread related sections - Start + * + *********************************************/ + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* RT-Thread related sections - end */ + + /* section information for usbh class */ + . = ALIGN(8); + __usbh_class_info_start__ = .; + KEEP(*(.usbh_class_info)) + __usbh_class_info_end__ = .; + + } > XPI0 + + .rel : { + KEEP(*(.rel*)) + } > XPI0 + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .fast_ram (NOLOAD) : { + KEEP(*(.fast_ram)) + } > DLM + + .bss(NOLOAD) : { + . = ALIGN(8); + __bss_start__ = .; + *(.bss) + *(.bss*) + *(.sbss*) + *(.scommon) + *(.scommon*) + *(.dynsbss*) + *(COMMON) + . = ALIGN(8); + _end = .; + __bss_end__ = .; + } > AXI_SRAM + + /* Note: the .tbss and .tdata section should be adjacent */ + .tbss(NOLOAD) : { + . = ALIGN(8); + __tbss_start__ = .; + *(.tbss*) + *(.tcommon*) + _end = .; + __tbss_end__ = .; + } > AXI_SRAM + + .tdata : AT(etext) { + . = ALIGN(8); + __tdata_start__ = .; + __thread_pointer = .; + *(.tdata) + *(.tdata*) + . = ALIGN(8); + __tdata_end__ = .; + } > AXI_SRAM + + .data : AT(etext + __tdata_end__ - __tdata_start__) { + . = ALIGN(8); + __data_start__ = .; + __global_pointer$ = . + 0x800; + *(.data) + *(.data*) + *(.sdata) + *(.sdata*) + + KEEP(*(.jcr)) + KEEP(*(.dynamic)) + KEEP(*(.got*)) + KEEP(*(.got)) + KEEP(*(.gcc_except_table)) + KEEP(*(.gcc_except_table.*)) + + . = ALIGN(8); + PROVIDE(__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE(__preinit_array_end = .); + + . = ALIGN(8); + PROVIDE(__init_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE(__init_array_end = .); + + . = ALIGN(8); + PROVIDE(__finit_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.finit_array.*))) + KEEP(*(.finit_array)) + PROVIDE(__finit_array_end = .); + + . = ALIGN(8); + PROVIDE(__ctors_start__ = .); + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(8); + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + . = ALIGN(8); + __data_end__ = .; + PROVIDE (__edata = .); + PROVIDE (_edata = .); + PROVIDE (edata = .); + } > AXI_SRAM + __fw_size__ = __data_end__ - __tdata_start__ + etext - __app_load_addr__; + + .heap(NOLOAD) : { + . = ALIGN(8); + __heap_start__ = .; + . += HEAP_SIZE; + __heap_end__ = .; + } > AXI_SRAM + + .framebuffer (NOLOAD) : { + . = ALIGN(8); + KEEP(*(.framebuffer)) + . = ALIGN(8); + } > AXI_SRAM + + .stack(NOLOAD) : { + . = ALIGN(8); + __stack_base__ = .; + . += STACK_SIZE; + . = ALIGN(8); + PROVIDE (_stack = .); + PROVIDE (_stack_in_dlm = .); + PROVIDE( __rt_rvstack = . ); + } > AXI_SRAM + + .noncacheable.init : AT(etext + __data_end__ - __tdata_start__ + __ramfunc_end__ - __ramfunc_start__) { + . = ALIGN(8); + __noncacheable_init_start__ = .; + KEEP(*(.noncacheable.init)) + __noncacheable_init_end__ = .; + . = ALIGN(8); + } > NONCACHEABLE_RAM + + .noncacheable.bss (NOLOAD) : { + . = ALIGN(8); + KEEP(*(.noncacheable)) + __noncacheable_bss_start__ = .; + KEEP(*(.noncacheable.bss)) + __noncacheable_bss_end__ = .; + . = ALIGN(8); + } > NONCACHEABLE_RAM + + .ahb_sram (NOLOAD) : { + KEEP(*(.ahb_sram)) + } > AHB_SRAM + + __noncacheable_start__ = ORIGIN(NONCACHEABLE_RAM); + __noncacheable_end__ = ORIGIN(NONCACHEABLE_RAM) + LENGTH(NONCACHEABLE_RAM); + +} diff --git a/bsp/hpmicro/hpm6e00evk/board/linker_scripts/flash_rtt_enet.ld b/bsp/hpmicro/hpm6e00evk/board/linker_scripts/flash_rtt_enet.ld new file mode 100644 index 0000000000..26ed72c84a --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/linker_scripts/flash_rtt_enet.ld @@ -0,0 +1,316 @@ +/* + * Copyright 2021-2024 HPMicro + * SPDX-License-Identifier: BSD-3-Clause + */ + +ENTRY(_start) + +STACK_SIZE = DEFINED(_stack_size) ? _stack_size : 0x4000; +HEAP_SIZE = DEFINED(_heap_size) ? _heap_size : 128K; +FLASH_SIZE = DEFINED(_flash_size) ? _flash_size : 16M; +NONCACHEABLE_SIZE = DEFINED(_noncacheable_size) ? _noncacheable_size : 512K; + +MEMORY +{ + XPI0 (rx) : ORIGIN = 0x80000000, LENGTH = FLASH_SIZE + ILM (wx) : ORIGIN = 0, LENGTH = 256K + DLM (w) : ORIGIN = 0x00200000, LENGTH = 256K + AXI_SRAM (wx) : ORIGIN = 0x01200000, LENGTH = 512K + NONCACHEABLE_RAM (wx) : ORIGIN = 0x01280000, LENGTH = NONCACHEABLE_SIZE + AHB_SRAM (w): ORIGIN = 0xF0200000, LENGTH = 32k +} + +__nor_cfg_option_load_addr__ = ORIGIN(XPI0) + 0x400; +__boot_header_load_addr__ = ORIGIN(XPI0) + 0x1000; +__app_load_addr__ = ORIGIN(XPI0) + 0x3000; +__boot_header_length__ = __boot_header_end__ - __boot_header_start__; +__app_offset__ = __app_load_addr__ - __boot_header_load_addr__; + +SECTIONS +{ + .nor_cfg_option __nor_cfg_option_load_addr__ : { + KEEP(*(.nor_cfg_option)) + } > XPI0 + + .boot_header __boot_header_load_addr__ : { + __boot_header_start__ = .; + KEEP(*(.boot_header)) + KEEP(*(.fw_info_table)) + KEEP(*(.dc_info)) + __boot_header_end__ = .; + } > XPI0 + + .start __app_load_addr__ : { + . = ALIGN(8); + KEEP(*(.start)) + } > XPI0 + + __vector_load_addr__ = ADDR(.start) + SIZEOF(.start); + .vectors : AT(__vector_load_addr__) { + . = ALIGN(8); + __vector_ram_start__ = .; + KEEP(*(.vector_table)) + KEEP(*(.isr_vector)) + + . = ALIGN(8); + __vector_ram_end__ = .; + } > ILM + + .fast : AT(etext + __data_end__ - __tdata_start__) { + . = ALIGN(8); + __ramfunc_start__ = .; + *(.fast) + + /* RT-Thread Core Start */ + KEEP(*context_gcc.o(.text* .rodata*)) + KEEP(*port*.o (.text .text* .rodata .rodata*)) + KEEP(*interrupt_gcc.o (.text .text* .rodata .rodata*)) + KEEP(*trap_common.o (.text .text* .rodata .rodata*)) + KEEP(*irq.o (.text .text* .rodata .rodata*)) + KEEP(*clock.o (.text .text* .rodata .rodata*)) + KEEP(*kservice.o (.text .text* .rodata .rodata*)) + KEEP(*scheduler*.o (.text .text* .rodata .rodata*)) + KEEP(*trap*.o (.text .text* .rodata .rodata*)) + KEEP(*idle.o (.text .text* .rodata .rodata*)) + KEEP(*ipc.o (.text .text* .rodata .rodata*)) + KEEP(*slab.o (.text .text* .rodata .rodata*)) + KEEP(*thread.o (.text .text* .rodata .rodata*)) + KEEP(*object.o (.text .text* .rodata .rodata*)) + KEEP(*timer.o (.text .text* .rodata .rodata*)) + KEEP(*mem.o (.text .text* .rodata .rodata*)) + KEEP(*memheap.o (.text .text* .rodata .rodata*)) + KEEP(*mempool.o (.text .text* .rodata .rodata*)) + /* RT-Thread Core End */ + + /* HPMicro Driver Wrapper */ + KEEP(*drv_*.o (.text .text* .rodata .rodata*)) + KEEP(*api_lib*.o (.text .text* .rodata .rodata*)) + KEEP(*api_msg*.o (.text .text* .rodata .rodata*)) + KEEP(*if_api*.o (.text .text* .rodata .rodata*)) + KEEP(*netbuf*.o (.text .text* .rodata .rodata*)) + KEEP(*netdb*.o (.text .text* .rodata .rodata*)) + KEEP(*netifapi*.o (.text .text* .rodata .rodata*)) + KEEP(*sockets*.o (.text .text* .rodata .rodata*)) + KEEP(*tcpip*.o (.text .text* .rodata .rodata*)) + KEEP(*inet_chksum*.o (.text .text* .rodata .rodata*)) + KEEP(*ip*.o (.text .text* .rodata .rodata*)) + KEEP(*memp*.o (.text .text* .rodata .rodata*)) + KEEP(*netif*.o (.text .text* .rodata .rodata*)) + KEEP(*pbuf*.o (.text .text* .rodata .rodata*)) + KEEP(*tcp_in*.o (.text .text* .rodata .rodata*)) + KEEP(*tcp_out*.o (.text .text* .rodata .rodata*)) + KEEP(*tcp*.o (.text .text* .rodata .rodata*)) + KEEP(*ethernet*.o (.text .text* .rodata .rodata*)) + KEEP(*ethernetif*.o (.text .text* .rodata .rodata*)) + + . = ALIGN(8); + __ramfunc_end__ = .; + } > ILM + + .fast_ram (NOLOAD) : { + KEEP(*(.fast_ram)) + } > DLM + + .text (__vector_load_addr__ + __vector_ram_end__ - __vector_ram_start__) : { + . = ALIGN(8); + *(.text) + *(.text*) + *(.rodata) + *(.rodata*) + *(.srodata) + *(.srodata*) + + *(.hash) + *(.dyn*) + *(.gnu*) + *(.pl*) + + KEEP(*(.eh_frame)) + *(.eh_frame*) + + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(8); + + /********************************************* + * + * RT-Thread related sections - Start + * + *********************************************/ + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* RT-Thread related sections - end */ + + /* section information for usbh class */ + . = ALIGN(8); + __usbh_class_info_start__ = .; + KEEP(*(.usbh_class_info)) + __usbh_class_info_end__ = .; + + } > XPI0 + + .rel : { + KEEP(*(.rel*)) + } > XPI0 + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .bss(NOLOAD) : { + . = ALIGN(8); + __bss_start__ = .; + *(.bss) + *(.bss*) + *(.sbss*) + *(.scommon) + *(.scommon*) + *(.dynsbss*) + *(COMMON) + . = ALIGN(8); + _end = .; + __bss_end__ = .; + } > AXI_SRAM + + /* Note: the .tbss and .tdata section should be adjacent */ + .tbss(NOLOAD) : { + . = ALIGN(8); + __tbss_start__ = .; + *(.tbss*) + *(.tcommon*) + _end = .; + __tbss_end__ = .; + } > AXI_SRAM + + .tdata : AT(etext) { + . = ALIGN(8); + __tdata_start__ = .; + __thread_pointer = .; + *(.tdata) + *(.tdata*) + . = ALIGN(8); + __tdata_end__ = .; + } > AXI_SRAM + + .data : AT(etext + __tdata_end__ - __tdata_start__) { + . = ALIGN(8); + __data_start__ = .; + __global_pointer$ = . + 0x800; + *(.data) + *(.data*) + *(.sdata) + *(.sdata*) + + KEEP(*(.jcr)) + KEEP(*(.dynamic)) + KEEP(*(.got*)) + KEEP(*(.got)) + KEEP(*(.gcc_except_table)) + KEEP(*(.gcc_except_table.*)) + + . = ALIGN(8); + PROVIDE(__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE(__preinit_array_end = .); + + . = ALIGN(8); + PROVIDE(__init_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE(__init_array_end = .); + + . = ALIGN(8); + PROVIDE(__finit_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.finit_array.*))) + KEEP(*(.finit_array)) + PROVIDE(__finit_array_end = .); + + . = ALIGN(8); + PROVIDE(__ctors_start__ = .); + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(8); + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + . = ALIGN(8); + __data_end__ = .; + PROVIDE (__edata = .); + PROVIDE (_edata = .); + PROVIDE (edata = .); + } > AXI_SRAM + __fw_size__ = __data_end__ - __tdata_start__ + etext - __app_load_addr__; + + .heap(NOLOAD) : { + . = ALIGN(8); + __heap_start__ = .; + . += HEAP_SIZE; + __heap_end__ = .; + } > AXI_SRAM + + .framebuffer (NOLOAD) : { + . = ALIGN(8); + KEEP(*(.framebuffer)) + . = ALIGN(8); + } > AXI_SRAM + + .stack(NOLOAD) : { + . = ALIGN(8); + __stack_base__ = .; + . += STACK_SIZE; + . = ALIGN(8); + PROVIDE (_stack = .); + PROVIDE (_stack_in_dlm = .); + PROVIDE( __rt_rvstack = . ); + } > AXI_SRAM + + .noncacheable.init : AT(etext + __data_end__ - __tdata_start__ + __ramfunc_end__ - __ramfunc_start__) { + . = ALIGN(8); + __noncacheable_init_start__ = .; + KEEP(*(.noncacheable.init)) + __noncacheable_init_end__ = .; + . = ALIGN(8); + } > NONCACHEABLE_RAM + + .noncacheable.bss (NOLOAD) : { + . = ALIGN(8); + KEEP(*(.noncacheable)) + __noncacheable_bss_start__ = .; + KEEP(*(.noncacheable.bss)) + __noncacheable_bss_end__ = .; + . = ALIGN(8); + } > NONCACHEABLE_RAM + + .ahb_sram (NOLOAD) : { + KEEP(*(.ahb_sram)) + } > AHB_SRAM + + __noncacheable_start__ = ORIGIN(NONCACHEABLE_RAM); + __noncacheable_end__ = ORIGIN(NONCACHEABLE_RAM) + LENGTH(NONCACHEABLE_RAM); +} diff --git a/bsp/hpmicro/hpm6e00evk/board/linker_scripts/ram_rtt.ld b/bsp/hpmicro/hpm6e00evk/board/linker_scripts/ram_rtt.ld new file mode 100644 index 0000000000..79769ad59d --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/linker_scripts/ram_rtt.ld @@ -0,0 +1,248 @@ +/* + * Copyright 2021-2023 HPMicro + * SPDX-License-Identifier: BSD-3-Clause + */ + +ENTRY(_start) + +STACK_SIZE = DEFINED(_stack_size) ? _stack_size : 0x4000; +HEAP_SIZE = DEFINED(_heap_size) ? _heap_size : 128K; +NONCACHEABLE_SIZE = DEFINED(_noncacheable_size) ? _noncacheable_size : 512K; + +MEMORY +{ + ILM (wx) : ORIGIN = 0, LENGTH = 256K + DLM (w) : ORIGIN = 0x00200000, LENGTH = 256K + AXI_SRAM (wx) : ORIGIN = 0x01200000, LENGTH = 512K + NONCACHEABLE_RAM (wx) : ORIGIN = 0x01280000, LENGTH = NONCACHEABLE_SIZE + AHB_SRAM (w) : ORIGIN = 0xF0200000, LENGTH = 32k +} + +SECTIONS +{ + .start : { + . = ALIGN(8); + KEEP(*(.start)) + } > ILM + + .vectors : { + . = ALIGN(8); + KEEP(*(.isr_vector)) + KEEP(*(.vector_table)) + . = ALIGN(8); + } > ILM + + .text : { + . = ALIGN(8); + *(.text) + *(.text*) + *(.rodata) + *(.rodata*) + *(.srodata) + *(.srodata*) + + *(.hash) + *(.dyn*) + *(.gnu*) + *(.pl*) + *(FalPartTable) + + KEEP(*(.eh_frame)) + *(.eh_frame*) + + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(8); + + /********************************************* + * + * RT-Thread related sections - Start + * + *********************************************/ + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* RT-Thread related sections - end */ + + /* section information for usbh class */ + . = ALIGN(8); + __usbh_class_info_start__ = .; + KEEP(*(.usbh_class_info)) + __usbh_class_info_end__ = .; + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + } > ILM + + .rel : { + KEEP(*(.rel*)) + } > AXI_SRAM + + .fast_ram (NOLOAD) : { + KEEP(*(.fast_ram)) + } > DLM + + .bss(NOLOAD) : { + . = ALIGN(8); + __bss_start__ = .; + *(.bss) + *(.bss*) + *(.sbss*) + *(.scommon) + *(.scommon*) + *(.dynsbss*) + *(COMMON) + . = ALIGN(8); + _end = .; + __bss_end__ = .; + } > DLM + + /* Note: .tbss and .tdata should be adjacent */ + .tbss(NOLOAD) : { + . = ALIGN(8); + __tbss_start__ = .; + *(.tbss*) + *(.tcommon*) + _end = .; + __tbss_end__ = .; + } > DLM + + .tdata : AT(etext) { + . = ALIGN(8); + __tdata_start__ = .; + __thread_pointer = .; + *(.tdata) + *(.tdata*) + . = ALIGN(8); + __tdata_end__ = .; + } > DLM + + .data : AT(etext + __tdata_end__ - __tdata_start__) { + . = ALIGN(8); + __data_start__ = .; + __global_pointer$ = . + 0x800; + *(.data) + *(.data*) + *(.sdata) + *(.sdata*) + + KEEP(*(.jcr)) + KEEP(*(.dynamic)) + KEEP(*(.got*)) + KEEP(*(.got)) + KEEP(*(.gcc_except_table)) + KEEP(*(.gcc_except_table.*)) + + . = ALIGN(8); + PROVIDE(__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE(__preinit_array_end = .); + + . = ALIGN(8); + PROVIDE(__init_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE(__init_array_end = .); + + . = ALIGN(8); + PROVIDE(__finit_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.finit_array.*))) + KEEP(*(.finit_array)) + PROVIDE(__finit_array_end = .); + + . = ALIGN(8); + PROVIDE(__ctors_start__ = .); + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(8); + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + + . = ALIGN(8); + __data_end__ = .; + PROVIDE (__edata = .); + PROVIDE (_edata = .); + PROVIDE (edata = .); + } > DLM + + .fast : AT(etext + __data_end__ - __tdata_start__) { + . = ALIGN(8); + PROVIDE(__ramfunc_start__ = .); + *(.fast) + . = ALIGN(8); + PROVIDE(__ramfunc_end__ = .); + } > AXI_SRAM + + .noncacheable.init : AT(etext + __data_end__ - __tdata_start__ + __ramfunc_end__ - __ramfunc_start__) { + . = ALIGN(8); + __noncacheable_init_start__ = .; + KEEP(*(.noncacheable.init)) + __noncacheable_init_end__ = .; + . = ALIGN(8); + } > NONCACHEABLE_RAM + + .noncacheable.bss (NOLOAD) : { + . = ALIGN(8); + KEEP(*(.noncacheable)) + __noncacheable_bss_start__ = .; + KEEP(*(.noncacheable.bss)) + __noncacheable_bss_end__ = .; + . = ALIGN(8); + } > NONCACHEABLE_RAM + + __noncacheable_start__ = ORIGIN(NONCACHEABLE_RAM); + __noncacheable_end__ = ORIGIN(NONCACHEABLE_RAM) + LENGTH(NONCACHEABLE_RAM); + + .ahb_sram (NOLOAD) : { + KEEP(*(.ahb_sram)) + } > AHB_SRAM + + .stack(NOLOAD) : { + . = ALIGN(8); + __stack_base__ = .; + . += STACK_SIZE; + PROVIDE (_stack = .); + PROVIDE (_stack_in_dlm = .); + PROVIDE (__rt_rvstack = .); + } > DLM + + .framebuffer (NOLOAD) : { + KEEP(*(.framebuffer)) + } > AXI_SRAM + + .heap (NOLOAD) : { + . = ALIGN(8); + __heap_start__ = .; + . += HEAP_SIZE; + __heap_end__ = .; + + } > AXI_SRAM + +} diff --git a/bsp/hpmicro/hpm6e00evk/board/pinmux.c b/bsp/hpmicro/hpm6e00evk/board/pinmux.c new file mode 100644 index 0000000000..27f72fa1cb --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/pinmux.c @@ -0,0 +1,699 @@ +/* + * Copyright (c) 2023-2024 hpmicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +/* + * 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 "board.h" + +void init_uart_pins(UART_Type *ptr) +{ + if (ptr == HPM_UART0) { + HPM_IOC->PAD[IOC_PAD_PA00].FUNC_CTL = IOC_PA00_FUNC_CTL_UART0_TXD; + HPM_IOC->PAD[IOC_PAD_PA01].FUNC_CTL = IOC_PA01_FUNC_CTL_UART0_RXD; + } else if (ptr == HPM_UART1) { + HPM_IOC->PAD[IOC_PAD_PY07].FUNC_CTL = IOC_PY07_FUNC_CTL_UART1_TXD; + 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_UART1_RXD; + HPM_PIOC->PAD[IOC_PAD_PY06].FUNC_CTL = PIOC_PY06_FUNC_CTL_SOC_PY_06; + } else if (ptr == HPM_UART14) { + HPM_IOC->PAD[IOC_PAD_PF24].FUNC_CTL = IOC_PF24_FUNC_CTL_UART14_TXD; + HPM_IOC->PAD[IOC_PAD_PF25].FUNC_CTL = IOC_PF25_FUNC_CTL_UART14_RXD; + } else if (ptr == HPM_PUART) { + HPM_PIOC->PAD[IOC_PAD_PY00].FUNC_CTL = PIOC_PY00_FUNC_CTL_PURT_TXD; + HPM_PIOC->PAD[IOC_PAD_PY01].FUNC_CTL = PIOC_PY01_FUNC_CTL_PURT_RXD; + } else { + ; + } +} + +void init_uart_pin_as_gpio(UART_Type *ptr) +{ + if (ptr == HPM_UART0) { + /* pull-up */ + HPM_IOC->PAD[IOC_PAD_PA00].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); + HPM_IOC->PAD[IOC_PAD_PA01].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); + + HPM_IOC->PAD[IOC_PAD_PA00].FUNC_CTL = IOC_PA00_FUNC_CTL_GPIO_A_00; + HPM_IOC->PAD[IOC_PAD_PA01].FUNC_CTL = IOC_PA01_FUNC_CTL_GPIO_A_01; + } +} + +void init_i2c_pins(I2C_Type *ptr) +{ + if (ptr == HPM_I2C0) { + HPM_IOC->PAD[IOC_PAD_PY02].FUNC_CTL = IOC_PY02_FUNC_CTL_I2C0_SCL | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + HPM_IOC->PAD[IOC_PAD_PY03].FUNC_CTL = IOC_PY03_FUNC_CTL_I2C0_SDA | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + HPM_IOC->PAD[IOC_PAD_PY02].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); + HPM_IOC->PAD[IOC_PAD_PY03].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); + HPM_IOC->PAD[IOC_PAD_PY02].PAD_CTL = IOC_PAD_PAD_CTL_OD_MASK; + HPM_IOC->PAD[IOC_PAD_PY03].PAD_CTL = IOC_PAD_PAD_CTL_OD_MASK; + HPM_PIOC->PAD[IOC_PAD_PY02].FUNC_CTL = PIOC_PY02_FUNC_CTL_SOC_PY_02; + HPM_PIOC->PAD[IOC_PAD_PY03].FUNC_CTL = PIOC_PY03_FUNC_CTL_SOC_PY_03; + + } else if (ptr == HPM_I2C1) { + /* WM8960 audio_codec */ + HPM_IOC->PAD[IOC_PAD_PF12].FUNC_CTL = IOC_PF12_FUNC_CTL_I2C1_SDA | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + HPM_IOC->PAD[IOC_PAD_PF13].FUNC_CTL = IOC_PF13_FUNC_CTL_I2C1_SCL | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + HPM_IOC->PAD[IOC_PAD_PF12].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); + HPM_IOC->PAD[IOC_PAD_PF13].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); + HPM_IOC->PAD[IOC_PAD_PF12].PAD_CTL = IOC_PAD_PAD_CTL_OD_MASK; + HPM_IOC->PAD[IOC_PAD_PF13].PAD_CTL = IOC_PAD_PAD_CTL_OD_MASK; + } else { + ; + } +} + +void init_i2c_pins_as_gpio(I2C_Type *ptr) +{ + if (ptr == HPM_I2C0) { + HPM_IOC->PAD[IOC_PAD_PY02].FUNC_CTL = IOC_PY02_FUNC_CTL_GPIO_Y_02; + HPM_IOC->PAD[IOC_PAD_PY03].FUNC_CTL = IOC_PY03_FUNC_CTL_GPIO_Y_03; + HPM_PIOC->PAD[IOC_PAD_PY02].FUNC_CTL = PIOC_PY02_FUNC_CTL_PGPIO_Y_02; + HPM_PIOC->PAD[IOC_PAD_PY03].FUNC_CTL = PIOC_PY03_FUNC_CTL_PGPIO_Y_03; + } else if (ptr == HPM_I2C1) { +#if 1 + /* WM8960 audio_codec */ + HPM_IOC->PAD[IOC_PAD_PF12].FUNC_CTL = IOC_PF12_FUNC_CTL_I2C1_SDA | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + HPM_IOC->PAD[IOC_PAD_PF13].FUNC_CTL = IOC_PF13_FUNC_CTL_I2C1_SCL | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; +#else + /* raspberry-Pi_IF */ + HPM_IOC->PAD[IOC_PAD_PY06].FUNC_CTL = IOC_PY06_FUNC_CTL_I2C1_SDA | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + HPM_IOC->PAD[IOC_PAD_PY07].FUNC_CTL = IOC_PY07_FUNC_CTL_I2C1_SCL | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + HPM_PIOC->PAD[IOC_PAD_PY06].FUNC_CTL = PIOC_PY06_FUNC_CTL_GPIO_Y_06; + HPM_PIOC->PAD[IOC_PAD_PY07].FUNC_CTL = PIOC_PY07_FUNC_CTL_GPIO_Y_07; +#endif + } else { + ; + } +} + +void init_femc_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PD02].FUNC_CTL = IOC_PD02_FUNC_CTL_FEMC_A_00; + HPM_IOC->PAD[IOC_PAD_PD03].FUNC_CTL = IOC_PD03_FUNC_CTL_FEMC_A_01; + HPM_IOC->PAD[IOC_PAD_PD00].FUNC_CTL = IOC_PD00_FUNC_CTL_FEMC_A_02; + HPM_IOC->PAD[IOC_PAD_PD01].FUNC_CTL = IOC_PD01_FUNC_CTL_FEMC_A_03; + HPM_IOC->PAD[IOC_PAD_PC18].FUNC_CTL = IOC_PC18_FUNC_CTL_FEMC_A_04; + HPM_IOC->PAD[IOC_PAD_PC19].FUNC_CTL = IOC_PC19_FUNC_CTL_FEMC_A_05; + HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_FEMC_A_06; + HPM_IOC->PAD[IOC_PAD_PC21].FUNC_CTL = IOC_PC21_FUNC_CTL_FEMC_A_07; + HPM_IOC->PAD[IOC_PAD_PC23].FUNC_CTL = IOC_PC23_FUNC_CTL_FEMC_A_08; + HPM_IOC->PAD[IOC_PAD_PC24].FUNC_CTL = IOC_PC24_FUNC_CTL_FEMC_A_09; + HPM_IOC->PAD[IOC_PAD_PD04].FUNC_CTL = IOC_PD04_FUNC_CTL_FEMC_A_10; + HPM_IOC->PAD[IOC_PAD_PC25].FUNC_CTL = IOC_PC25_FUNC_CTL_FEMC_A_11; /* SRAM: NWE */ + HPM_IOC->PAD[IOC_PAD_PC26].FUNC_CTL = IOC_PC26_FUNC_CTL_FEMC_A_12; /* SRAM: NOE */ + + HPM_IOC->PAD[IOC_PAD_PD31].FUNC_CTL = IOC_PD31_FUNC_CTL_FEMC_DQ_00; + HPM_IOC->PAD[IOC_PAD_PD30].FUNC_CTL = IOC_PD30_FUNC_CTL_FEMC_DQ_01; + HPM_IOC->PAD[IOC_PAD_PD29].FUNC_CTL = IOC_PD29_FUNC_CTL_FEMC_DQ_02; + HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = IOC_PD28_FUNC_CTL_FEMC_DQ_03; + HPM_IOC->PAD[IOC_PAD_PD27].FUNC_CTL = IOC_PD27_FUNC_CTL_FEMC_DQ_04; + HPM_IOC->PAD[IOC_PAD_PD26].FUNC_CTL = IOC_PD26_FUNC_CTL_FEMC_DQ_05; + HPM_IOC->PAD[IOC_PAD_PD24].FUNC_CTL = IOC_PD24_FUNC_CTL_FEMC_DQ_06; + HPM_IOC->PAD[IOC_PAD_PD25].FUNC_CTL = IOC_PD25_FUNC_CTL_FEMC_DQ_07; + HPM_IOC->PAD[IOC_PAD_PD14].FUNC_CTL = IOC_PD14_FUNC_CTL_FEMC_DQ_08; + HPM_IOC->PAD[IOC_PAD_PD17].FUNC_CTL = IOC_PD17_FUNC_CTL_FEMC_DQ_09; + HPM_IOC->PAD[IOC_PAD_PD16].FUNC_CTL = IOC_PD16_FUNC_CTL_FEMC_DQ_10; + HPM_IOC->PAD[IOC_PAD_PD19].FUNC_CTL = IOC_PD19_FUNC_CTL_FEMC_DQ_11; + HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_FEMC_DQ_12; + HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_FEMC_DQ_13; + HPM_IOC->PAD[IOC_PAD_PD20].FUNC_CTL = IOC_PD20_FUNC_CTL_FEMC_DQ_14; + HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_FEMC_DQ_15; + HPM_IOC->PAD[IOC_PAD_PC16].FUNC_CTL = IOC_PC16_FUNC_CTL_FEMC_DQ_16; + HPM_IOC->PAD[IOC_PAD_PC17].FUNC_CTL = IOC_PC17_FUNC_CTL_FEMC_DQ_17; + HPM_IOC->PAD[IOC_PAD_PC13].FUNC_CTL = IOC_PC13_FUNC_CTL_FEMC_DQ_18; + HPM_IOC->PAD[IOC_PAD_PC14].FUNC_CTL = IOC_PC14_FUNC_CTL_FEMC_DQ_19; + HPM_IOC->PAD[IOC_PAD_PC10].FUNC_CTL = IOC_PC10_FUNC_CTL_FEMC_DQ_20; + HPM_IOC->PAD[IOC_PAD_PC11].FUNC_CTL = IOC_PC11_FUNC_CTL_FEMC_DQ_21; + HPM_IOC->PAD[IOC_PAD_PC02].FUNC_CTL = IOC_PC02_FUNC_CTL_FEMC_DQ_22; + HPM_IOC->PAD[IOC_PAD_PC09].FUNC_CTL = IOC_PC09_FUNC_CTL_FEMC_DQ_23; + HPM_IOC->PAD[IOC_PAD_PC00].FUNC_CTL = IOC_PC00_FUNC_CTL_FEMC_DQ_24; + HPM_IOC->PAD[IOC_PAD_PC01].FUNC_CTL = IOC_PC01_FUNC_CTL_FEMC_DQ_25; + HPM_IOC->PAD[IOC_PAD_PC03].FUNC_CTL = IOC_PC03_FUNC_CTL_FEMC_DQ_26; + HPM_IOC->PAD[IOC_PAD_PC04].FUNC_CTL = IOC_PC04_FUNC_CTL_FEMC_DQ_27; + HPM_IOC->PAD[IOC_PAD_PC05].FUNC_CTL = IOC_PC05_FUNC_CTL_FEMC_DQ_28; + HPM_IOC->PAD[IOC_PAD_PC06].FUNC_CTL = IOC_PC06_FUNC_CTL_FEMC_DQ_29; + HPM_IOC->PAD[IOC_PAD_PC07].FUNC_CTL = IOC_PC07_FUNC_CTL_FEMC_DQ_30; + HPM_IOC->PAD[IOC_PAD_PC08].FUNC_CTL = IOC_PC08_FUNC_CTL_FEMC_DQ_31; + + HPM_IOC->PAD[IOC_PAD_PD23].FUNC_CTL = IOC_PD23_FUNC_CTL_FEMC_DM_0; /* SRAM: NLB */ + HPM_IOC->PAD[IOC_PAD_PD15].FUNC_CTL = IOC_PD15_FUNC_CTL_FEMC_DM_1; /* SRAM: NUB */ + HPM_IOC->PAD[IOC_PAD_PC12].FUNC_CTL = IOC_PC12_FUNC_CTL_FEMC_DM_2; + HPM_IOC->PAD[IOC_PAD_PC15].FUNC_CTL = IOC_PC15_FUNC_CTL_FEMC_DM_3; + + HPM_IOC->PAD[IOC_PAD_PX07].FUNC_CTL = IOC_PX07_FUNC_CTL_FEMC_DQS | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + + /* SDRAM */ + HPM_IOC->PAD[IOC_PAD_PD05].FUNC_CTL = IOC_PD05_FUNC_CTL_FEMC_BA0; + HPM_IOC->PAD[IOC_PAD_PD06].FUNC_CTL = IOC_PD06_FUNC_CTL_FEMC_BA1; /* SRAM: NADV */ + HPM_IOC->PAD[IOC_PAD_PD10].FUNC_CTL = IOC_PD10_FUNC_CTL_FEMC_RAS; + HPM_IOC->PAD[IOC_PAD_PD13].FUNC_CTL = IOC_PD13_FUNC_CTL_FEMC_CAS; + HPM_IOC->PAD[IOC_PAD_PC28].FUNC_CTL = IOC_PC28_FUNC_CTL_FEMC_CKE; + HPM_IOC->PAD[IOC_PAD_PC27].FUNC_CTL = IOC_PC27_FUNC_CTL_FEMC_CLK_0; + HPM_IOC->PAD[IOC_PAD_PD12].FUNC_CTL = IOC_PD12_FUNC_CTL_FEMC_WE; + HPM_IOC->PAD[IOC_PAD_PD11].FUNC_CTL = IOC_PD11_FUNC_CTL_FEMC_CS_0; + HPM_IOC->PAD[IOC_PAD_PD08].FUNC_CTL = IOC_PD08_FUNC_CTL_FEMC_CS_1; + + /* SRAM */ + HPM_IOC->PAD[IOC_PAD_PC29].FUNC_CTL = IOC_PC29_FUNC_CTL_FEMC_SCLK_0; + HPM_IOC->PAD[IOC_PAD_PD07].FUNC_CTL = IOC_PD07_FUNC_CTL_FEMC_SCLK_1; + HPM_IOC->PAD[IOC_PAD_PC30].FUNC_CTL = IOC_PC30_FUNC_CTL_FEMC_SCS_0; + HPM_IOC->PAD[IOC_PAD_PC31].FUNC_CTL = IOC_PC31_FUNC_CTL_FEMC_SCS_1; + HPM_IOC->PAD[IOC_PAD_PC22].FUNC_CTL = IOC_PC22_FUNC_CTL_FEMC_SRDY; +} + +void init_ppi_pins(void) +{ + /* DQ Group A */ + HPM_IOC->PAD[IOC_PAD_PD31].FUNC_CTL = IOC_PD31_FUNC_CTL_PPI0_DQ_00; + HPM_IOC->PAD[IOC_PAD_PD30].FUNC_CTL = IOC_PD30_FUNC_CTL_PPI0_DQ_01; + HPM_IOC->PAD[IOC_PAD_PD29].FUNC_CTL = IOC_PD29_FUNC_CTL_PPI0_DQ_02; + HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = IOC_PD28_FUNC_CTL_PPI0_DQ_03; + HPM_IOC->PAD[IOC_PAD_PD27].FUNC_CTL = IOC_PD27_FUNC_CTL_PPI0_DQ_04; + HPM_IOC->PAD[IOC_PAD_PD26].FUNC_CTL = IOC_PD26_FUNC_CTL_PPI0_DQ_05; + HPM_IOC->PAD[IOC_PAD_PD24].FUNC_CTL = IOC_PD24_FUNC_CTL_PPI0_DQ_06; + HPM_IOC->PAD[IOC_PAD_PD25].FUNC_CTL = IOC_PD25_FUNC_CTL_PPI0_DQ_07; + HPM_IOC->PAD[IOC_PAD_PD14].FUNC_CTL = IOC_PD14_FUNC_CTL_PPI0_DQ_08; + HPM_IOC->PAD[IOC_PAD_PD17].FUNC_CTL = IOC_PD17_FUNC_CTL_PPI0_DQ_09; + HPM_IOC->PAD[IOC_PAD_PD16].FUNC_CTL = IOC_PD16_FUNC_CTL_PPI0_DQ_10; + HPM_IOC->PAD[IOC_PAD_PD19].FUNC_CTL = IOC_PD19_FUNC_CTL_PPI0_DQ_11; + HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_PPI0_DQ_12; + HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_PPI0_DQ_13; + HPM_IOC->PAD[IOC_PAD_PD20].FUNC_CTL = IOC_PD20_FUNC_CTL_PPI0_DQ_14; + HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_PPI0_DQ_15; + HPM_IOC->PAD[IOC_PAD_PC16].FUNC_CTL = IOC_PC16_FUNC_CTL_PPI0_DQ_16; + HPM_IOC->PAD[IOC_PAD_PC17].FUNC_CTL = IOC_PC17_FUNC_CTL_PPI0_DQ_17; + HPM_IOC->PAD[IOC_PAD_PC13].FUNC_CTL = IOC_PC13_FUNC_CTL_PPI0_DQ_18; + HPM_IOC->PAD[IOC_PAD_PC14].FUNC_CTL = IOC_PC14_FUNC_CTL_PPI0_DQ_19; + HPM_IOC->PAD[IOC_PAD_PC10].FUNC_CTL = IOC_PC10_FUNC_CTL_PPI0_DQ_20; + HPM_IOC->PAD[IOC_PAD_PC11].FUNC_CTL = IOC_PC11_FUNC_CTL_PPI0_DQ_21; + HPM_IOC->PAD[IOC_PAD_PC02].FUNC_CTL = IOC_PC02_FUNC_CTL_PPI0_DQ_22; + HPM_IOC->PAD[IOC_PAD_PC09].FUNC_CTL = IOC_PC09_FUNC_CTL_PPI0_DQ_23; + HPM_IOC->PAD[IOC_PAD_PC00].FUNC_CTL = IOC_PC00_FUNC_CTL_PPI0_DQ_24; + HPM_IOC->PAD[IOC_PAD_PC01].FUNC_CTL = IOC_PC01_FUNC_CTL_PPI0_DQ_25; + HPM_IOC->PAD[IOC_PAD_PC03].FUNC_CTL = IOC_PC03_FUNC_CTL_PPI0_DQ_26; + HPM_IOC->PAD[IOC_PAD_PC04].FUNC_CTL = IOC_PC04_FUNC_CTL_PPI0_DQ_27; + HPM_IOC->PAD[IOC_PAD_PC05].FUNC_CTL = IOC_PC05_FUNC_CTL_PPI0_DQ_28; + HPM_IOC->PAD[IOC_PAD_PC06].FUNC_CTL = IOC_PC06_FUNC_CTL_PPI0_DQ_29; + HPM_IOC->PAD[IOC_PAD_PC07].FUNC_CTL = IOC_PC07_FUNC_CTL_PPI0_DQ_30; + HPM_IOC->PAD[IOC_PAD_PC08].FUNC_CTL = IOC_PC08_FUNC_CTL_PPI0_DQ_31; + + /* DM Group A */ + HPM_IOC->PAD[IOC_PAD_PD23].FUNC_CTL = IOC_PD23_FUNC_CTL_PPI0_DM_0; + HPM_IOC->PAD[IOC_PAD_PD15].FUNC_CTL = IOC_PD15_FUNC_CTL_PPI0_DM_1; + HPM_IOC->PAD[IOC_PAD_PC12].FUNC_CTL = IOC_PC12_FUNC_CTL_PPI0_DM_2; + HPM_IOC->PAD[IOC_PAD_PC15].FUNC_CTL = IOC_PC15_FUNC_CTL_PPI0_DM_3; + + /* CS */ + HPM_IOC->PAD[IOC_PAD_PC30].FUNC_CTL = IOC_PC30_FUNC_CTL_PPI0_CS_0; + HPM_IOC->PAD[IOC_PAD_PC31].FUNC_CTL = IOC_PC31_FUNC_CTL_PPI0_CS_1; + HPM_IOC->PAD[IOC_PAD_PD11].FUNC_CTL = IOC_PD11_FUNC_CTL_PPI0_CS_2; + HPM_IOC->PAD[IOC_PAD_PD08].FUNC_CTL = IOC_PD08_FUNC_CTL_PPI0_CS_3; + + /* CTRL */ + HPM_IOC->PAD[IOC_PAD_PC27].FUNC_CTL = IOC_PC27_FUNC_CTL_PPI0_CTR_0; + HPM_IOC->PAD[IOC_PAD_PD10].FUNC_CTL = IOC_PD10_FUNC_CTL_PPI0_CTR_1; + HPM_IOC->PAD[IOC_PAD_PC22].FUNC_CTL = IOC_PC22_FUNC_CTL_PPI0_CTR_2; + HPM_IOC->PAD[IOC_PAD_PD07].FUNC_CTL = IOC_PD07_FUNC_CTL_PPI0_CTR_3; + HPM_IOC->PAD[IOC_PAD_PE00].FUNC_CTL = IOC_PE00_FUNC_CTL_PPI0_CTR_4; + HPM_IOC->PAD[IOC_PAD_PE01].FUNC_CTL = IOC_PE01_FUNC_CTL_PPI0_CTR_5; + HPM_IOC->PAD[IOC_PAD_PE02].FUNC_CTL = IOC_PE02_FUNC_CTL_PPI0_CTR_6; + HPM_IOC->PAD[IOC_PAD_PE03].FUNC_CTL = IOC_PE03_FUNC_CTL_PPI0_CTR_7; + + /* CLK */ + HPM_IOC->PAD[IOC_PAD_PC29].FUNC_CTL = IOC_PC29_FUNC_CTL_PPI0_CLK; + + /* DQ Group B */ + /* + * HPM_IOC->PAD[IOC_PAD_PD02].FUNC_CTL = IOC_PD02_FUNC_CTL_PPI0_DQ_00; + * HPM_IOC->PAD[IOC_PAD_PD03].FUNC_CTL = IOC_PD03_FUNC_CTL_PPI0_DQ_01; + * HPM_IOC->PAD[IOC_PAD_PD00].FUNC_CTL = IOC_PD00_FUNC_CTL_PPI0_DQ_02; + * HPM_IOC->PAD[IOC_PAD_PD01].FUNC_CTL = IOC_PD01_FUNC_CTL_PPI0_DQ_03; + * HPM_IOC->PAD[IOC_PAD_PC18].FUNC_CTL = IOC_PC18_FUNC_CTL_PPI0_DQ_04; + * HPM_IOC->PAD[IOC_PAD_PC19].FUNC_CTL = IOC_PC19_FUNC_CTL_PPI0_DQ_05; + * HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_PPI0_DQ_06; + * HPM_IOC->PAD[IOC_PAD_PC21].FUNC_CTL = IOC_PC21_FUNC_CTL_PPI0_DQ_07; + * HPM_IOC->PAD[IOC_PAD_PC23].FUNC_CTL = IOC_PC23_FUNC_CTL_PPI0_DQ_08; + * HPM_IOC->PAD[IOC_PAD_PC24].FUNC_CTL = IOC_PC24_FUNC_CTL_PPI0_DQ_09; + * HPM_IOC->PAD[IOC_PAD_PD04].FUNC_CTL = IOC_PD04_FUNC_CTL_PPI0_DQ_10; + * HPM_IOC->PAD[IOC_PAD_PC25].FUNC_CTL = IOC_PC25_FUNC_CTL_PPI0_DQ_11; + * HPM_IOC->PAD[IOC_PAD_PC26].FUNC_CTL = IOC_PC26_FUNC_CTL_PPI0_DQ_12; + * HPM_IOC->PAD[IOC_PAD_PD05].FUNC_CTL = IOC_PD05_FUNC_CTL_PPI0_DQ_13; + * HPM_IOC->PAD[IOC_PAD_PD06].FUNC_CTL = IOC_PD06_FUNC_CTL_PPI0_DQ_14; + * HPM_IOC->PAD[IOC_PAD_PD12].FUNC_CTL = IOC_PD12_FUNC_CTL_PPI0_DQ_15; + */ + + /* DM Group B */ + /* + * HPM_IOC->PAD[IOC_PAD_PC28].FUNC_CTL = IOC_PC28_FUNC_CTL_PPI0_DM_0; + * HPM_IOC->PAD[IOC_PAD_PD13].FUNC_CTL = IOC_PD13_FUNC_CTL_PPI0_DM_1; + */ +} + +void init_sdm_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PF17].FUNC_CTL = IOC_PF17_FUNC_CTL_SDM0_CLK_0; + HPM_IOC->PAD[IOC_PAD_PF16].FUNC_CTL = IOC_PF16_FUNC_CTL_SDM0_DAT_0; +} + +void init_pwm_pin_as_sdm_clock(void) +{ + HPM_IOC->PAD[IOC_PAD_PE19].FUNC_CTL = IOC_PE19_FUNC_CTL_PWM2_P_3; +} + +void init_gpio_pins(void) +{ + /* configure pad setting: pull enable and pull up, schmitt trigger enable */ + /* enable schmitt trigger to eliminate jitter of pin used as button */ + + /* Button */ + uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1); + HPM_IOC->PAD[IOC_PAD_PB25].FUNC_CTL = IOC_PB25_FUNC_CTL_GPIO_B_25; + HPM_IOC->PAD[IOC_PAD_PB25].PAD_CTL = pad_ctl; + HPM_IOC->PAD[IOC_PAD_PB24].FUNC_CTL = IOC_PB24_FUNC_CTL_GPIO_B_24; + HPM_IOC->PAD[IOC_PAD_PB24].PAD_CTL = pad_ctl; +} + +void init_spi_pins(SPI_Type *ptr) +{ + if (ptr == HPM_SPI7) { + HPM_IOC->PAD[IOC_PAD_PF27].FUNC_CTL = IOC_PF27_FUNC_CTL_SPI7_CS_0; + HPM_IOC->PAD[IOC_PAD_PF26].FUNC_CTL = IOC_PF26_FUNC_CTL_SPI7_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_SET(1); + HPM_IOC->PAD[IOC_PAD_PF28].FUNC_CTL = IOC_PF28_FUNC_CTL_SPI7_MISO; + HPM_IOC->PAD[IOC_PAD_PF29].FUNC_CTL = IOC_PF29_FUNC_CTL_SPI7_MOSI; + } else { + ; + } +} + +void init_spi_pins_with_gpio_as_cs(SPI_Type *ptr) +{ + if (ptr == HPM_SPI7) { + HPM_IOC->PAD[IOC_PAD_PF27].FUNC_CTL = IOC_PF27_FUNC_CTL_GPIO_F_27; + HPM_IOC->PAD[IOC_PAD_PF26].FUNC_CTL = IOC_PF26_FUNC_CTL_SPI7_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_SET(1); + HPM_IOC->PAD[IOC_PAD_PF28].FUNC_CTL = IOC_PF28_FUNC_CTL_SPI7_MISO; + HPM_IOC->PAD[IOC_PAD_PF29].FUNC_CTL = IOC_PF29_FUNC_CTL_SPI7_MOSI; + } +} + +void init_gptmr_pins(GPTMR_Type *ptr) +{ + if (ptr == HPM_GPTMR4) { + HPM_IOC->PAD[IOC_PAD_PB06].FUNC_CTL = IOC_PB06_FUNC_CTL_GPTMR4_CAPT_0; + HPM_IOC->PAD[IOC_PAD_PB07].FUNC_CTL = IOC_PB07_FUNC_CTL_GPTMR4_COMP_0; + } + if (ptr == HPM_GPTMR0) { + HPM_IOC->PAD[IOC_PAD_PE07].FUNC_CTL = IOC_PE07_FUNC_CTL_GPTMR0_COMP_0; + } + if (ptr == HPM_GPTMR5) { + HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_GPTMR5_COMP_2; + + } +} + +void init_hall_trgm_pins(void) +{ + init_qeiv2_uvw_pins(BOARD_BLDC_QEIV2_BASE); +} + +void init_qei_trgm_pins(void) +{ + init_qeiv2_ab_pins(BOARD_BLDC_QEIV2_BASE); +} + +void init_butn_pins(void) +{ + /* configure pad setting: pull enable and pull up, schmitt trigger enable */ + /* enable schmitt trigger to eliminate jitter of pin used as button */ + + /* Button */ + uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1); + HPM_IOC->PAD[IOC_PAD_PB24].FUNC_CTL = IOC_PB24_FUNC_CTL_GPIO_B_24; + HPM_IOC->PAD[IOC_PAD_PB24].PAD_CTL = pad_ctl; + HPM_IOC->PAD[IOC_PAD_PB25].FUNC_CTL = IOC_PB25_FUNC_CTL_GPIO_B_25; + HPM_IOC->PAD[IOC_PAD_PB25].PAD_CTL = pad_ctl; +} + +void init_acmp_pins(void) +{ + /* configure to CMP0_INN4 function */ + HPM_IOC->PAD[IOC_PAD_PF05].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; +} + +void init_pwm_fault_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_TRGM_P_05; +} + +void init_pwm_pins(PWMV2_Type *ptr) +{ + if (ptr == HPM_PWM1) { + HPM_IOC->PAD[IOC_PAD_PE08].FUNC_CTL = IOC_PE08_FUNC_CTL_PWM1_P_0; + HPM_IOC->PAD[IOC_PAD_PE09].FUNC_CTL = IOC_PE09_FUNC_CTL_PWM1_P_1; + HPM_IOC->PAD[IOC_PAD_PE10].FUNC_CTL = IOC_PE10_FUNC_CTL_PWM1_P_2; + HPM_IOC->PAD[IOC_PAD_PE11].FUNC_CTL = IOC_PE11_FUNC_CTL_PWM1_P_3; + HPM_IOC->PAD[IOC_PAD_PE12].FUNC_CTL = IOC_PE12_FUNC_CTL_PWM1_P_4; + HPM_IOC->PAD[IOC_PAD_PE13].FUNC_CTL = IOC_PE13_FUNC_CTL_PWM1_P_5; + } else { + ; + } +} + +void init_usb_pins(void) +{ + /* USB0_ID */ + HPM_IOC->PAD[IOC_PAD_PF22].FUNC_CTL = IOC_PF22_FUNC_CTL_USB0_ID; + /* USB0_OC */ + HPM_IOC->PAD[IOC_PAD_PF23].FUNC_CTL = IOC_PF23_FUNC_CTL_USB0_OC; + /* USB0_PWR */ + HPM_IOC->PAD[IOC_PAD_PF19].FUNC_CTL = IOC_PF19_FUNC_CTL_USB0_PWR; +} + +void init_clk_obs_pins(void) +{ + /* HPM_IOC->PAD[IOC_PAD_PB02].FUNC_CTL = IOC_PB02_FUNC_CTL_SYSCTL_CLK_OBS_0; */ +} + +void init_i2s_pins(I2S_Type *ptr) +{ + if (ptr == HPM_I2S0) { + HPM_IOC->PAD[IOC_PAD_PB11].FUNC_CTL = IOC_PB11_FUNC_CTL_I2S0_MCLK; + HPM_IOC->PAD[IOC_PAD_PB01].FUNC_CTL = IOC_PB01_FUNC_CTL_I2S0_BCLK; + HPM_IOC->PAD[IOC_PAD_PB10].FUNC_CTL = IOC_PB10_FUNC_CTL_I2S0_FCLK; + HPM_IOC->PAD[IOC_PAD_PB00].FUNC_CTL = IOC_PB00_FUNC_CTL_I2S0_TXD_0; + HPM_IOC->PAD[IOC_PAD_PB08].FUNC_CTL = IOC_PB08_FUNC_CTL_I2S0_RXD_0; + } else { + ; + } +} + +void init_qeo_pins(QEOV2_Type *ptr) +{ + if (ptr == HPM_QEO0) { + HPM_IOC->PAD[IOC_PAD_PE07].FUNC_CTL = IOC_PE07_FUNC_CTL_QEO0_A; /* Motor CON3 */ + HPM_IOC->PAD[IOC_PAD_PE06].FUNC_CTL = IOC_PE06_FUNC_CTL_QEO0_B; + HPM_IOC->PAD[IOC_PAD_PE05].FUNC_CTL = IOC_PE05_FUNC_CTL_QEO0_Z; + } else { + ; + } +} + +void init_sei_pins(SEI_Type *ptr, uint8_t sei_ctrl_idx) +{ + if (ptr == HPM_SEI) { + if (sei_ctrl_idx == SEI_CTRL_1) { + HPM_IOC->PAD[IOC_PAD_PE18].FUNC_CTL = IOC_PE18_FUNC_CTL_SEI1_DE; + HPM_IOC->PAD[IOC_PAD_PE19].FUNC_CTL = IOC_PE19_FUNC_CTL_SEI1_CK; + HPM_IOC->PAD[IOC_PAD_PE16].FUNC_CTL = IOC_PE16_FUNC_CTL_SEI1_TX; + HPM_IOC->PAD[IOC_PAD_PE17].FUNC_CTL = IOC_PE17_FUNC_CTL_SEI1_RX; + } else { + ; + } + } +} + +void init_qeiv2_uvw_pins(QEIV2_Type *ptr) +{ + if (ptr == HPM_QEI0) { + HPM_IOC->PAD[IOC_PAD_PB07].FUNC_CTL = IOC_PB07_FUNC_CTL_QEI0_A; + HPM_IOC->PAD[IOC_PAD_PB06].FUNC_CTL = IOC_PB06_FUNC_CTL_QEI0_B; + HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_QEI0_Z; + } +} + +void init_qeiv2_ab_pins(QEIV2_Type *ptr) +{ + if (ptr == HPM_QEI0) { + HPM_IOC->PAD[IOC_PAD_PB07].FUNC_CTL = IOC_PB07_FUNC_CTL_QEI0_A; + HPM_IOC->PAD[IOC_PAD_PB06].FUNC_CTL = IOC_PB06_FUNC_CTL_QEI0_B; + } +} + +void init_qeiv2_abz_pins(QEIV2_Type *ptr) +{ + if (ptr == HPM_QEI0) { + HPM_IOC->PAD[IOC_PAD_PB07].FUNC_CTL = IOC_PB07_FUNC_CTL_QEI0_A; + HPM_IOC->PAD[IOC_PAD_PB06].FUNC_CTL = IOC_PB06_FUNC_CTL_QEI0_B; + HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_QEI0_Z; + } +} + +void init_rdc_pin(void) +{ + HPM_IOC->PAD[IOC_PAD_PF06].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_IU: ADC0.14 / ADC1.14 PWN_P */ + HPM_IOC->PAD[IOC_PAD_PF08].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_IV: ADC0.10 / ADC1.10 PWN_N */ + HPM_IOC->PAD[IOC_PAD_PE08].FUNC_CTL = IOC_PE08_FUNC_CTL_RDC0_PWM_N; +/*The GPIO is designed for debug */ +#ifdef RDC_SAMPLE_TEST_GPIO_OUTPUT + HPM_IOC->PAD[IOC_PAD_PB00].FUNC_CTL = IOC_PB00_FUNC_CTL_TRGM_P_00; +#endif +} + +void init_dao_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PF04].FUNC_CTL = IOC_PF04_FUNC_CTL_DAO_RP; + HPM_IOC->PAD[IOC_PAD_PF03].FUNC_CTL = IOC_PF03_FUNC_CTL_DAO_RN; +} + +void init_pdm_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PB02].FUNC_CTL = IOC_PB02_FUNC_CTL_PDM0_CLK; + HPM_IOC->PAD[IOC_PAD_PB03].FUNC_CTL = IOC_PB03_FUNC_CTL_PDM0_D_0; +} + +void init_enet_pins(ENET_Type *ptr) +{ + if (ptr == HPM_ENET0) { + HPM_IOC->PAD[IOC_PAD_PF01].FUNC_CTL = IOC_PF01_FUNC_CTL_ETH0_MDIO; + HPM_IOC->PAD[IOC_PAD_PF00].FUNC_CTL = IOC_PF00_FUNC_CTL_ETH0_MDC; + + HPM_IOC->PAD[IOC_PAD_PE20].FUNC_CTL = IOC_PE20_FUNC_CTL_ETH0_RXDV; + HPM_IOC->PAD[IOC_PAD_PE21].FUNC_CTL = IOC_PE21_FUNC_CTL_ETH0_RXD_0; + HPM_IOC->PAD[IOC_PAD_PE22].FUNC_CTL = IOC_PE22_FUNC_CTL_ETH0_RXD_1; + HPM_IOC->PAD[IOC_PAD_PE23].FUNC_CTL = IOC_PE23_FUNC_CTL_ETH0_RXD_2; + HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PE24_FUNC_CTL_ETH0_RXD_3; + HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_ETH0_RXCK; + + HPM_IOC->PAD[IOC_PAD_PE26].FUNC_CTL = IOC_PE26_FUNC_CTL_ETH0_TXCK; + HPM_IOC->PAD[IOC_PAD_PE27].FUNC_CTL = IOC_PE27_FUNC_CTL_ETH0_TXD_0; + HPM_IOC->PAD[IOC_PAD_PE28].FUNC_CTL = IOC_PE28_FUNC_CTL_ETH0_TXD_1; + HPM_IOC->PAD[IOC_PAD_PE29].FUNC_CTL = IOC_PE29_FUNC_CTL_ETH0_TXD_2; + HPM_IOC->PAD[IOC_PAD_PE30].FUNC_CTL = IOC_PE30_FUNC_CTL_ETH0_TXD_3; + HPM_IOC->PAD[IOC_PAD_PE31].FUNC_CTL = IOC_PE31_FUNC_CTL_ETH0_TXEN; + } +} + +void init_enet_pps_pins(void) +{ + +} + +void init_adc16_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PF07].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC0.IN15 */ + HPM_IOC->PAD[IOC_PAD_PF02].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC0.IN15 */ +} + +void init_adc_bldc_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PF06].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_IU: ADC0.14 / ADC1.14 */ + HPM_IOC->PAD[IOC_PAD_PF08].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_IV: ADC0.10 / ADC1.10 */ + HPM_IOC->PAD[IOC_PAD_PF19].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_IW: ADC2.11 / ADC3.11 */ + + HPM_IOC->PAD[IOC_PAD_PF10].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_A: ADC0.1 / ADC1.1 */ + HPM_IOC->PAD[IOC_PAD_PF07].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_B: ADC0.15 / ADC1.15 */ + HPM_IOC->PAD[IOC_PAD_PF27].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_C: ADC2.00 / ADC3.00 */ + HPM_IOC->PAD[IOC_PAD_PF20].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_D: ADC2.03 / ADC3.03 */ + +} + +void init_adc_qeiv2_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PF19].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_IW: ADC2.11 / ADC3.11 cos_ch */ + HPM_IOC->PAD[IOC_PAD_PF06].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC_IU: ADC0.14 / ADC1.14 sin_ch */ +} + +void init_can_pins(MCAN_Type *ptr) +{ + if (ptr == HPM_MCAN4) { + HPM_IOC->PAD[IOC_PAD_PZ00].FUNC_CTL = IOC_PZ00_FUNC_CTL_MCAN4_TXD; + HPM_BIOC->PAD[IOC_PAD_PZ00].FUNC_CTL = BIOC_PZ00_FUNC_CTL_SOC_PZ_00; + HPM_IOC->PAD[IOC_PAD_PZ01].FUNC_CTL = IOC_PZ01_FUNC_CTL_MCAN4_RXD; + HPM_BIOC->PAD[IOC_PAD_PZ01].FUNC_CTL = BIOC_PZ01_FUNC_CTL_SOC_PZ_01; + HPM_IOC->PAD[IOC_PAD_PZ02].FUNC_CTL = IOC_PZ02_FUNC_CTL_MCAN4_STBY; + HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = BIOC_PZ02_FUNC_CTL_SOC_PZ_02; + } else { + /* Invalid CAN instance */ + } +} + +void init_led_pins_as_gpio(void) +{ + HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_GPIO_E_04; + HPM_IOC->PAD[IOC_PAD_PE14].FUNC_CTL = IOC_PE14_FUNC_CTL_GPIO_E_14; + HPM_IOC->PAD[IOC_PAD_PE15].FUNC_CTL = IOC_PE15_FUNC_CTL_GPIO_E_15; +} + +void init_led_pins_as_pwm(void) +{ + /* Red */ + HPM_IOC->PAD[IOC_PAD_PE14].FUNC_CTL = IOC_PE14_FUNC_CTL_PWM1_P_6; + /* Green */ + HPM_IOC->PAD[IOC_PAD_PE15].FUNC_CTL = IOC_PE15_FUNC_CTL_PWM1_P_7; + /* BLUE */ + HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_PWM0_P_4; +} + +void init_plb_pins(void) +{ + HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_TRGM_P_05; +} + +void init_esc_pins(void) +{ + /* ESC */ + HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = IOC_PA09_FUNC_CTL_ESC0_REFCK; + HPM_IOC->PAD[IOC_PAD_PA30].FUNC_CTL = IOC_PA30_FUNC_CTL_ESC0_MDIO; + HPM_IOC->PAD[IOC_PAD_PA31].FUNC_CTL = IOC_PA31_FUNC_CTL_ESC0_MDC; + HPM_IOC->PAD[IOC_PAD_PA12].FUNC_CTL = IOC_PA12_FUNC_CTL_ESC0_SDA; + HPM_IOC->PAD[IOC_PAD_PA13].FUNC_CTL = IOC_PA13_FUNC_CTL_ESC0_SCL; + + /* ESC needs to configure these pins for specific functions, see ESC IOCFG registers */ + HPM_IOC->PAD[IOC_PAD_PA10].FUNC_CTL = IOC_PA10_FUNC_CTL_GPIO_A_10; /* GPIO to reset PHY */ + HPM_IOC->PAD[IOC_PAD_PA15].FUNC_CTL = IOC_PA15_FUNC_CTL_ESC0_CTR_3; /* NMII_LINK0(PORTA_LINK) function */ + HPM_IOC->PAD[IOC_PAD_PA11].FUNC_CTL = IOC_PA11_FUNC_CTL_ESC0_CTR_0; /* NMII_LINK1(PORTB_LINK) function */ + HPM_IOC->PAD[IOC_PAD_PE02].FUNC_CTL = IOC_PE02_FUNC_CTL_ESC0_CTR_6; /* LED_ERROR function */ + HPM_IOC->PAD[IOC_PAD_PE03].FUNC_CTL = IOC_PE03_FUNC_CTL_ESC0_CTR_1; /* LED_RUN function */ + + /* ESC PORTA */ + HPM_IOC->PAD[IOC_PAD_PA24].FUNC_CTL = IOC_PA24_FUNC_CTL_ESC0_P0_TXCK; + HPM_IOC->PAD[IOC_PAD_PA29].FUNC_CTL = IOC_PA29_FUNC_CTL_ESC0_P0_TXEN; + HPM_IOC->PAD[IOC_PAD_PA25].FUNC_CTL = IOC_PA25_FUNC_CTL_ESC0_P0_TXD_0; + HPM_IOC->PAD[IOC_PAD_PA26].FUNC_CTL = IOC_PA26_FUNC_CTL_ESC0_P0_TXD_1; + HPM_IOC->PAD[IOC_PAD_PA27].FUNC_CTL = IOC_PA27_FUNC_CTL_ESC0_P0_TXD_2; + HPM_IOC->PAD[IOC_PAD_PA28].FUNC_CTL = IOC_PA28_FUNC_CTL_ESC0_P0_TXD_3; + HPM_IOC->PAD[IOC_PAD_PA21].FUNC_CTL = IOC_PA21_FUNC_CTL_ESC0_P0_RXCK; + HPM_IOC->PAD[IOC_PAD_PA16].FUNC_CTL = IOC_PA16_FUNC_CTL_ESC0_P0_RXDV; + HPM_IOC->PAD[IOC_PAD_PA23].FUNC_CTL = IOC_PA23_FUNC_CTL_ESC0_P0_RXER; + HPM_IOC->PAD[IOC_PAD_PA17].FUNC_CTL = IOC_PA17_FUNC_CTL_ESC0_P0_RXD_0; + HPM_IOC->PAD[IOC_PAD_PA18].FUNC_CTL = IOC_PA18_FUNC_CTL_ESC0_P0_RXD_1; + HPM_IOC->PAD[IOC_PAD_PA19].FUNC_CTL = IOC_PA19_FUNC_CTL_ESC0_P0_RXD_2; + HPM_IOC->PAD[IOC_PAD_PA20].FUNC_CTL = IOC_PA20_FUNC_CTL_ESC0_P0_RXD_3; + + /* ESC PORTB */ + HPM_IOC->PAD[IOC_PAD_PB18].FUNC_CTL = IOC_PB18_FUNC_CTL_ESC0_P1_TXCK; + HPM_IOC->PAD[IOC_PAD_PB23].FUNC_CTL = IOC_PB23_FUNC_CTL_ESC0_P1_TXEN; + HPM_IOC->PAD[IOC_PAD_PB19].FUNC_CTL = IOC_PB19_FUNC_CTL_ESC0_P1_TXD_0; + HPM_IOC->PAD[IOC_PAD_PB20].FUNC_CTL = IOC_PB20_FUNC_CTL_ESC0_P1_TXD_1; + HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_ESC0_P1_TXD_2; + HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_ESC0_P1_TXD_3; + HPM_IOC->PAD[IOC_PAD_PB17].FUNC_CTL = IOC_PB17_FUNC_CTL_ESC0_P1_RXCK; + HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_ESC0_P1_RXDV; + HPM_IOC->PAD[IOC_PAD_PA22].FUNC_CTL = IOC_PA22_FUNC_CTL_ESC0_P1_RXER; + HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_ESC0_P1_RXD_0; + HPM_IOC->PAD[IOC_PAD_PB14].FUNC_CTL = IOC_PB14_FUNC_CTL_ESC0_P1_RXD_1; + HPM_IOC->PAD[IOC_PAD_PB15].FUNC_CTL = IOC_PB15_FUNC_CTL_ESC0_P1_RXD_2; + HPM_IOC->PAD[IOC_PAD_PB16].FUNC_CTL = IOC_PB16_FUNC_CTL_ESC0_P1_RXD_3; +} + +void init_tsw_pins(void) +{ + /* PORT1 */ + HPM_IOC->PAD[IOC_PAD_PA16].FUNC_CTL = IOC_PA16_FUNC_CTL_TSW0_P1_RXDV; + HPM_IOC->PAD[IOC_PAD_PA21].FUNC_CTL = IOC_PA21_FUNC_CTL_TSW0_P1_RXCK; + HPM_IOC->PAD[IOC_PAD_PA17].FUNC_CTL = IOC_PA17_FUNC_CTL_TSW0_P1_RXD_0; + HPM_IOC->PAD[IOC_PAD_PA18].FUNC_CTL = IOC_PA18_FUNC_CTL_TSW0_P1_RXD_1; + HPM_IOC->PAD[IOC_PAD_PA19].FUNC_CTL = IOC_PA19_FUNC_CTL_TSW0_P1_RXD_2; + HPM_IOC->PAD[IOC_PAD_PA20].FUNC_CTL = IOC_PA20_FUNC_CTL_TSW0_P1_RXD_3; + + HPM_IOC->PAD[IOC_PAD_PA29].FUNC_CTL = IOC_PA29_FUNC_CTL_TSW0_P1_TXEN; + HPM_IOC->PAD[IOC_PAD_PA24].FUNC_CTL = IOC_PA24_FUNC_CTL_TSW0_P1_TXCK; + HPM_IOC->PAD[IOC_PAD_PA25].FUNC_CTL = IOC_PA25_FUNC_CTL_TSW0_P1_TXD_0; + HPM_IOC->PAD[IOC_PAD_PA26].FUNC_CTL = IOC_PA26_FUNC_CTL_TSW0_P1_TXD_1; + HPM_IOC->PAD[IOC_PAD_PA27].FUNC_CTL = IOC_PA27_FUNC_CTL_TSW0_P1_TXD_2; + HPM_IOC->PAD[IOC_PAD_PA28].FUNC_CTL = IOC_PA28_FUNC_CTL_TSW0_P1_TXD_3; + + HPM_IOC->PAD[IOC_PAD_PA23].FUNC_CTL = IOC_PA23_FUNC_CTL_TSW0_P1_RXER; + HPM_IOC->PAD[IOC_PAD_PA30].FUNC_CTL = IOC_PA30_FUNC_CTL_TSW0_P1_MDC; + HPM_IOC->PAD[IOC_PAD_PA31].FUNC_CTL = IOC_PA31_FUNC_CTL_TSW0_P1_MDIO; + + /* PORT2 */ + HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_TSW0_P2_RXDV; + HPM_IOC->PAD[IOC_PAD_PB17].FUNC_CTL = IOC_PB17_FUNC_CTL_TSW0_P2_RXCK; + HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_TSW0_P2_RXD_0; + HPM_IOC->PAD[IOC_PAD_PB14].FUNC_CTL = IOC_PB14_FUNC_CTL_TSW0_P2_RXD_1; + HPM_IOC->PAD[IOC_PAD_PB15].FUNC_CTL = IOC_PB15_FUNC_CTL_TSW0_P2_RXD_2; + HPM_IOC->PAD[IOC_PAD_PB16].FUNC_CTL = IOC_PB16_FUNC_CTL_TSW0_P2_RXD_3; + + HPM_IOC->PAD[IOC_PAD_PB23].FUNC_CTL = IOC_PB23_FUNC_CTL_TSW0_P2_TXEN; + HPM_IOC->PAD[IOC_PAD_PB18].FUNC_CTL = IOC_PB18_FUNC_CTL_TSW0_P2_TXCK; + HPM_IOC->PAD[IOC_PAD_PB19].FUNC_CTL = IOC_PB19_FUNC_CTL_TSW0_P2_TXD_0; + HPM_IOC->PAD[IOC_PAD_PB20].FUNC_CTL = IOC_PB20_FUNC_CTL_TSW0_P2_TXD_1; + HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_TSW0_P2_TXD_2; + HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_TSW0_P2_TXD_3; + + HPM_IOC->PAD[IOC_PAD_PA22].FUNC_CTL = IOC_PA22_FUNC_CTL_TSW0_P2_RXER; + HPM_IOC->PAD[IOC_PAD_PE03].FUNC_CTL = IOC_PE03_FUNC_CTL_TSW0_P2_MDC; + HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_TSW0_P2_MDIO; + + /* PORT1/PORT2 PHY RST */ + HPM_IOC->PAD[IOC_PAD_PA10].FUNC_CTL = IOC_PA10_FUNC_CTL_GPIO_A_10; + + /* XI */ + HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = IOC_PA09_FUNC_CTL_ESC0_REFCK; + + /* PORT3 PE */ + HPM_IOC->PAD[IOC_PAD_PE20].FUNC_CTL = IOC_PE20_FUNC_CTL_TSW0_P3_RXDV; + HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_TSW0_P3_RXCK; + HPM_IOC->PAD[IOC_PAD_PE21].FUNC_CTL = IOC_PE21_FUNC_CTL_TSW0_P3_RXD_0; + HPM_IOC->PAD[IOC_PAD_PE22].FUNC_CTL = IOC_PE22_FUNC_CTL_TSW0_P3_RXD_1; + HPM_IOC->PAD[IOC_PAD_PE23].FUNC_CTL = IOC_PE23_FUNC_CTL_TSW0_P3_RXD_2; + HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PE24_FUNC_CTL_TSW0_P3_RXD_3; + + HPM_IOC->PAD[IOC_PAD_PE31].FUNC_CTL = IOC_PE31_FUNC_CTL_TSW0_P3_TXEN; + HPM_IOC->PAD[IOC_PAD_PE26].FUNC_CTL = IOC_PE26_FUNC_CTL_TSW0_P3_TXCK; + HPM_IOC->PAD[IOC_PAD_PE27].FUNC_CTL = IOC_PE27_FUNC_CTL_TSW0_P3_TXD_0; + HPM_IOC->PAD[IOC_PAD_PE28].FUNC_CTL = IOC_PE28_FUNC_CTL_TSW0_P3_TXD_1; + HPM_IOC->PAD[IOC_PAD_PE29].FUNC_CTL = IOC_PE29_FUNC_CTL_TSW0_P3_TXD_2; + HPM_IOC->PAD[IOC_PAD_PE30].FUNC_CTL = IOC_PE30_FUNC_CTL_TSW0_P3_TXD_3; + + HPM_IOC->PAD[IOC_PAD_PF00].FUNC_CTL = IOC_PF00_FUNC_CTL_TSW0_P3_MDC; + HPM_IOC->PAD[IOC_PAD_PF01].FUNC_CTL = IOC_PF01_FUNC_CTL_TSW0_P3_MDIO; + + /* PORT3 PHY INT */ + HPM_IOC->PAD[IOC_PAD_PB09].FUNC_CTL = IOC_PB09_FUNC_CTL_GPIO_B_09; + + /* PORT3 PHY RST */ + HPM_IOC->PAD[IOC_PAD_PA14].FUNC_CTL = IOC_PA14_FUNC_CTL_GPIO_A_14; +} + +void init_tamper_pins(void) +{ + HPM_BIOC->PAD[IOC_PAD_PZ04].FUNC_CTL = BIOC_PZ04_FUNC_CTL_TAMP_PZ_04 | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; + HPM_BIOC->PAD[IOC_PAD_PZ05].FUNC_CTL = BIOC_PZ05_FUNC_CTL_TAMP_PZ_05; + HPM_BIOC->PAD[IOC_PAD_PZ03].FUNC_CTL = BIOC_PZ03_FUNC_CTL_TAMP_PZ_03; +} + +void init_esc_in_out_pin(void) +{ + HPM_IOC->PAD[IOC_PAD_PC31].FUNC_CTL = IOC_PC31_FUNC_CTL_GPIO_C_31; + HPM_IOC->PAD[IOC_PAD_PD08].FUNC_CTL = IOC_PD08_FUNC_CTL_GPIO_D_08; + HPM_IOC->PAD[IOC_PAD_PD09].FUNC_CTL = IOC_PD09_FUNC_CTL_GPIO_D_09; + HPM_IOC->PAD[IOC_PAD_PE14].FUNC_CTL = IOC_PE14_FUNC_CTL_GPIO_E_14; +} + +/* 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_PF27].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); + HPM_IOC->PAD[IOC_PAD_PF27].FUNC_CTL = IOC_PF27_FUNC_CTL_GPIO_F_27; +} \ No newline at end of file diff --git a/bsp/hpmicro/hpm6e00evk/board/pinmux.h b/bsp/hpmicro/hpm6e00evk/board/pinmux.h new file mode 100644 index 0000000000..13633d1160 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/pinmux.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 hpmicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef HPM_PINMUX_H +#define HPM_PINMUX_H + +#ifdef __cplusplus +extern "C" { +#endif +void init_uart_pins(UART_Type *ptr); +void init_uart_pin_as_gpio(UART_Type *ptr); +void init_i2c_pins_as_gpio(I2C_Type *ptr); +void init_i2c_pins(I2C_Type *ptr); +void init_femc_pins(void); +void init_ppi_pins(void); +void init_sdm_pins(void); +void init_pwm_pin_as_sdm_clock(void); +void init_gpio_pins(void); +void init_spi_pins(SPI_Type *ptr); +void init_spi_pins_with_gpio_as_cs(SPI_Type *ptr); +void init_gptmr_pins(GPTMR_Type *ptr); +void init_hall_trgm_pins(void); +void init_qei_trgm_pins(void); +void init_butn_pins(void); +void init_acmp_pins(void); +void init_pwm_pins(PWMV2_Type *ptr); +void init_usb_pins(void); +void init_i2s_pins(I2S_Type *ptr); +void init_qeo_pins(QEOV2_Type *ptr); +void init_sei_pins(SEI_Type *ptr, uint8_t sei_ctrl_idx); +void init_qeiv2_uvw_pins(QEIV2_Type *ptr); +void init_qeiv2_ab_pins(QEIV2_Type *ptr); +void init_qeiv2_abz_pins(QEIV2_Type *ptr); +void init_rdc_pin(void); +void init_dao_pins(void); +void init_pdm_pins(void); +void init_enet_pins(ENET_Type *ptr); +void init_enet_pps_pins(void); +void init_adc16_pins(void); +void init_adc_bldc_pins(void); +void init_adc_qeiv2_pins(void); +void init_can_pins(MCAN_Type *ptr); +void init_led_pins_as_gpio(void); +void init_led_pins_as_pwm(void); +void init_plb_pins(void); +void init_esc_pins(void); +void init_esc_in_out_pin(void); +void init_tsw_pins(void); +void init_tamper_pins(void); +void init_pwm_fault_pins(void); +void init_uart_break_signal_pin(void); + +#ifdef __cplusplus +} +#endif +#endif /* HPM_PINMUX_H */ diff --git a/bsp/hpmicro/hpm6e00evk/board/rtt_board.c b/bsp/hpmicro/hpm6e00evk/board/rtt_board.c new file mode 100644 index 0000000000..ac67a31d8a --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/rtt_board.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023-2024 HPMicro + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "board.h" +#include "rtt_board.h" +#include "hpm_uart_drv.h" +#include "hpm_gpio_drv.h" +#include "hpm_pmp_drv.h" +#include "assert.h" +#include "hpm_clock_drv.h" +#include "hpm_sysctl_drv.h" +#include +#include +#include "hpm_dma_mgr.h" +#include "hpm_mchtmr_drv.h" + +extern int rt_hw_uart_init(void); +void os_tick_config(void); +void rtt_board_init(void); + +void rt_hw_board_init(void) +{ + rtt_board_init(); + + /* Call the RT-Thread Component Board Initialization */ + rt_components_board_init(); +} + +void os_tick_config(void) +{ + sysctl_config_clock(HPM_SYSCTL, clock_node_mchtmr0, clock_source_osc0_clk0, 1); + sysctl_add_resource_to_cpu0(HPM_SYSCTL, sysctl_resource_mchtmr0); + mchtmr_set_compare_value(HPM_MCHTMR, BOARD_MCHTMR_FREQ_IN_HZ / RT_TICK_PER_SECOND); + enable_mchtmr_irq(); +} + +void rtt_board_init(void) +{ + board_init_clock(); + board_init_console(); + board_init_pmp(); + + dma_mgr_init(); + + /* initialize memory system */ + rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); + + /* Configure the OS Tick */ + os_tick_config(); + + /* Initialize the UART driver first, because later driver initialization may require the rt_kprintf */ + rt_hw_uart_init(); + + /* Set console device */ + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +} + +void app_init_led_pins(void) +{ + gpio_set_pin_output(APP_LED0_GPIO_CTRL, APP_LED0_GPIO_INDEX, APP_LED0_GPIO_PIN); + gpio_set_pin_output(APP_LED1_GPIO_CTRL, APP_LED1_GPIO_INDEX, APP_LED1_GPIO_PIN); + gpio_set_pin_output(APP_LED2_GPIO_CTRL, APP_LED2_GPIO_INDEX, APP_LED2_GPIO_PIN); + + gpio_write_pin(APP_LED0_GPIO_CTRL, APP_LED0_GPIO_INDEX, APP_LED0_GPIO_PIN, APP_LED_OFF); + gpio_write_pin(APP_LED1_GPIO_CTRL, APP_LED1_GPIO_INDEX, APP_LED1_GPIO_PIN, APP_LED_OFF); + gpio_write_pin(APP_LED2_GPIO_CTRL, APP_LED2_GPIO_INDEX, APP_LED2_GPIO_PIN, APP_LED_OFF); +} + +void app_led_write(uint32_t index, bool state) +{ + switch (index) + { + case 0: + gpio_write_pin(APP_LED0_GPIO_CTRL, APP_LED0_GPIO_INDEX, APP_LED0_GPIO_PIN, state); + break; + case 1: + gpio_write_pin(APP_LED1_GPIO_CTRL, APP_LED1_GPIO_INDEX, APP_LED1_GPIO_PIN, state); + break; + case 2: + gpio_write_pin(APP_LED2_GPIO_CTRL, APP_LED2_GPIO_INDEX, APP_LED2_GPIO_PIN, state); + break; + default: + /* Suppress the toolchain warnings */ + break; + } +} + +void rt_hw_console_output(const char *str) +{ + while (*str != '\0') + { + uart_send_byte(BOARD_APP_UART_BASE, *str++); + } +} + +void app_init_usb_pins(void) +{ + board_init_usb_pins(); +} + +ATTR_PLACE_AT(".isr_vector") void mchtmr_isr(void) +{ + HPM_MCHTMR->MTIMECMP = HPM_MCHTMR->MTIME + BOARD_MCHTMR_FREQ_IN_HZ / RT_TICK_PER_SECOND; + + rt_tick_increase(); +} + +void rt_hw_cpu_reset(void) +{ + HPM_PPOR->RESET_ENABLE = (1UL << 31); + HPM_PPOR->SOFTWARE_RESET = 1000U; + while(1) { + + } +} + +MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reset, reset the board); + +#ifdef RT_USING_CACHE +void rt_hw_cpu_dcache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_FLUSH) { + l1c_dc_flush((uint32_t)addr, size); + } else { + l1c_dc_invalidate((uint32_t)addr, size); + } +} +#endif diff --git a/bsp/hpmicro/hpm6e00evk/board/rtt_board.h b/bsp/hpmicro/hpm6e00evk/board/rtt_board.h new file mode 100644 index 0000000000..0c056aec76 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/board/rtt_board.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021 hpmicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef _RTT_BOARD_H +#define _RTT_BOARD_H +#include "hpm_common.h" +#include "hpm_soc.h" + +/* gpio section */ +#define APP_LED0_GPIO_CTRL HPM_GPIO0 +#define APP_LED0_GPIO_INDEX GPIO_DI_GPIOE +#define APP_LED0_GPIO_PIN 14 +#define APP_LED1_GPIO_CTRL HPM_GPIO0 +#define APP_LED1_GPIO_INDEX GPIO_DI_GPIOE +#define APP_LED1_GPIO_PIN 15 +#define APP_LED2_GPIO_CTRL HPM_GPIO0 +#define APP_LED2_GPIO_INDEX GPIO_DI_GPIOE +#define APP_LED2_GPIO_PIN 4 +#define APP_LED_ON (0) +#define APP_LED_OFF (1) + + + +/* mchtimer section */ +#define BOARD_MCHTMR_FREQ_IN_HZ (24000000UL) + +/* CAN section */ +#define BOARD_CAN_NAME "can4" +#define BOARD_CAN_HWFILTER_INDEX (4U) + +/* UART section */ +#define BOARD_UART_NAME "uart1" +#define BOARD_UART_RX_BUFFER_SIZE BSP_UART1_RX_BUFSIZE + + +/* audio section */ +#define BOARD_AUDIO_CODEC_I2C_NAME "i2c0" +#define BOARD_AUDIO_CODEC_I2S_NAME "i2s0" + +/* PWM section */ +#define BOARD_PWM_NAME "pwm1" +#define BOARD_PWM_CHANNEL (0U) + +#define IRQn_PendSV IRQn_DEBUG0 + +/*************************************************************** + * + * RT-Thread related definitions + * + **************************************************************/ +extern unsigned int __heap_start__; +extern unsigned int __heap_end__; + +#define RT_HW_HEAP_BEGIN ((void*)&__heap_start__) +#define RT_HW_HEAP_END ((void*)&__heap_end__) + + +typedef struct { + uint16_t vdd; + uint8_t bus_width; + uint8_t drive_strength; +}sdxc_io_cfg_t; + + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + + +void app_init_led_pins(void); +void app_led_write(uint32_t index, bool state); +void app_init_usb_pins(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ +#endif /* _RTT_BOARD_H */ diff --git a/bsp/hpmicro/hpm6e00evk/figures/board.png b/bsp/hpmicro/hpm6e00evk/figures/board.png new file mode 100644 index 0000000000000000000000000000000000000000..1795e32e21755665a08125cde25f33ddd9214119 GIT binary patch literal 327780 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
S*yi57{JhmZ{pg*a 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 W`rv(9XI=#XU-Ht*Qq>YB!T$roEOiqA literal 0 HcmV?d00001 diff --git a/bsp/hpmicro/hpm6e00evk/rtconfig.h b/bsp/hpmicro/hpm6e00evk/rtconfig.h new file mode 100644 index 0000000000..83bbddc032 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/rtconfig.h @@ -0,0 +1,337 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_CPUS_NR 1 +#define RT_ALIGN_SIZE 8 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 1024 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 1024 + +/* kservice optimization */ + +/* end of kservice optimization */ + +/* klibc optimization */ + +/* end of klibc optimization */ +#define RT_USING_DEBUG +#define RT_DEBUGING_ASSERT +#define RT_DEBUGING_COLOR +#define RT_DEBUGING_CONTEXT +#define RT_USING_OVERFLOW_CHECK + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE +/* end of Inter-Thread communication */ + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP +/* end of Memory Management */ +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart0" +#define RT_VER_NUM 0x50200 +#define RT_BACKTRACE_LEVEL_MAX_NR 32 +/* end of RT-Thread Kernel */ + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 +#define FINSH_USING_OPTION_COMPLETION + +/* DFS: device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V1 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define RT_USING_DFS_DEVFS +/* end of DFS: device virtual file system */ + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_PIN +/* end of Device Drivers */ + +/* C/C++ and POSIX layer */ + +/* ISO-ANSI C layer */ + +/* Timezone and Daylight Saving Time */ + +#define RT_LIBC_USING_LIGHT_TZ_DST +#define RT_LIBC_TZ_DEFAULT_HOUR 8 +#define RT_LIBC_TZ_DEFAULT_MIN 0 +#define RT_LIBC_TZ_DEFAULT_SEC 0 +/* end of Timezone and Daylight Saving Time */ +/* end of ISO-ANSI C layer */ + +/* POSIX (Portable Operating System Interface) layer */ + + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + +/* end of Interprocess Communication (IPC) */ +/* end of POSIX (Portable Operating System Interface) layer */ +/* end of C/C++ and POSIX layer */ + +/* Network */ + +/* end of Network */ + +/* Memory protection */ + +/* end of Memory protection */ + +/* Utilities */ + +/* end of Utilities */ + +/* Using USB legacy version */ + +/* end of Using USB legacy version */ +/* end of RT-Thread Components */ + +/* RT-Thread Utestcases */ + +/* end of RT-Thread Utestcases */ + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + +/* end of Marvell WiFi */ + +/* Wiced WiFi */ + +/* end of Wiced WiFi */ + +/* CYW43012 WiFi */ + +/* end of CYW43012 WiFi */ + +/* BL808 WiFi */ + +/* end of BL808 WiFi */ + +/* CYW43439 WiFi */ + +/* end of CYW43439 WiFi */ +/* end of Wi-Fi */ + +/* IoT Cloud */ + +/* end of IoT Cloud */ +/* end of IoT - internet of things */ + +/* security packages */ + +/* end of security packages */ + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + +/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */ + +/* XML: Extensible Markup Language */ + +/* end of XML: Extensible Markup Language */ +/* end of language packages */ + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + +/* end of LVGL: powerful and easy-to-use embedded GUI library */ + +/* u8g2: a monochrome graphic library */ + +/* end of u8g2: a monochrome graphic library */ +/* end of multimedia packages */ + +/* tools packages */ + +/* end of tools packages */ + +/* system packages */ + +/* enhanced kernel services */ + +/* end of enhanced kernel services */ + +/* acceleration: Assembly language or algorithmic acceleration packages */ + +/* end of acceleration: Assembly language or algorithmic acceleration packages */ + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + +/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + +/* Micrium: Micrium software products porting for RT-Thread */ + +/* end of Micrium: Micrium software products porting for RT-Thread */ +/* end of system packages */ + +/* peripheral libraries and drivers */ + +/* HAL & SDK Drivers */ + +/* STM32 HAL & SDK Drivers */ + +/* end of STM32 HAL & SDK Drivers */ + +/* Infineon HAL Packages */ + +/* end of Infineon HAL Packages */ + +/* Kendryte SDK */ + +/* end of Kendryte SDK */ +/* end of HAL & SDK Drivers */ + +/* sensors drivers */ + +/* end of sensors drivers */ + +/* touch drivers */ + +/* end of touch drivers */ +/* end of peripheral libraries and drivers */ + +/* AI packages */ + +/* end of AI packages */ + +/* Signal Processing and Control Algorithm Packages */ + +/* end of Signal Processing and Control Algorithm Packages */ + +/* miscellaneous packages */ + +/* project laboratory */ + +/* end of project laboratory */ + +/* samples: kernel and components samples */ + +/* end of samples: kernel and components samples */ + +/* entertainment: terminal games and other interesting software packages */ + +/* end of entertainment: terminal games and other interesting software packages */ +/* end of miscellaneous packages */ + +/* Arduino libraries */ + + +/* Projects and Demos */ + +/* end of Projects and Demos */ + +/* Sensors */ + +/* end of Sensors */ + +/* Display */ + +/* end of Display */ + +/* Timing */ + +/* end of Timing */ + +/* Data Processing */ + +/* end of Data Processing */ + +/* Data Storage */ + +/* Communication */ + +/* end of Communication */ + +/* Device Control */ + +/* end of Device Control */ + +/* Other */ + +/* end of Other */ + +/* Signal IO */ + +/* end of Signal IO */ + +/* Uncategorized */ + +/* end of Arduino libraries */ +/* end of RT-Thread online packages */ + +/* Hardware Drivers Config */ + +#define SOC_HPM6E00 + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_GPIO +#define BSP_USING_UART +#define BSP_USING_UART0 +/* end of On-chip Peripheral Drivers */ +/* end of Hardware Drivers Config */ + +#endif diff --git a/bsp/hpmicro/hpm6e00evk/rtconfig.py b/bsp/hpmicro/hpm6e00evk/rtconfig.py new file mode 100644 index 0000000000..0ef49a45d8 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/rtconfig.py @@ -0,0 +1,110 @@ +# Copyright 2021-2023 HPMicro +# SPDX-License-Identifier: BSD-3-Clause + +import os +import sys + +# toolchains options +ARCH='risc-v' +CPU='hpmicro' +SOC_FAMILY='HPM6E00' +CHIP_NAME='HPM6E80' + +CROSS_TOOL='gcc' + +# bsp lib config +BSP_LIBRARY_TYPE = None + +# Fallback toolchain info +FALLBACK_TOOLCHAIN_VENDOR='RISC-V' +FALLBACK_TOOLCHAIN_PKG='RISC-V-GCC-RV32' +FALLBACK_TOOLCHAIN_VER='2022-04-12' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +RTT_EXEC_PATH = os.getenv('RTT_EXEC_PATH') +if RTT_EXEC_PATH != None: + folders = RTT_EXEC_PATH.split(os.sep) + # If the `RT-Thread Env` is from the RT-Thread Studio, generate the RTT_EXEC_PATH using `FALLBACK_TOOLCHAIN_INFO` + if 'arm_gcc' in folders and 'platform' in folders: + RTT_EXEC_PATH = '' + for path in folders: + if path != 'platform': + RTT_EXEC_PATH = RTT_EXEC_PATH + path + os.sep + else: + break + RTT_EXEC_PATH = os.path.join(RTT_EXEC_PATH, 'repo', 'Extract', 'ToolChain_Support_Packages', FALLBACK_TOOLCHAIN_VENDOR, FALLBACK_TOOLCHAIN_PKG, FALLBACK_TOOLCHAIN_VER, 'bin') + # Override the 'RTT_RISCV_TOOLCHAIN' only if the `RT-Thread ENV` is from the RT-Thread Studio + if 'platform' in folders: + os.environ['RTT_RISCV_TOOLCHAIN'] = RTT_EXEC_PATH + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler path, for example, GNU RISC-V toolchain, IAR +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + if os.getenv('RTT_RISCV_TOOLCHAIN'): + EXEC_PATH = os.getenv('RTT_RISCV_TOOLCHAIN') + else: + EXEC_PATH = r'/opt/riscv-gnu-gcc/bin' +else: + print("CROSS_TOOL = {} not yet supported" % CROSS_TOOL) + +BUILD = 'flash_debug' + +if PLATFORM == 'gcc': + PREFIX = 'riscv32-unknown-elf-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + GDB = PREFIX + 'gdb' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + STRIP = PREFIX + 'strip' + + ARCH_ABI = ' -mcmodel=medlow ' + DEVICE = ARCH_ABI + ' -DUSE_NONVECTOR_MODE=1 ' + ' -ffunction-sections -fdata-sections -fno-common ' + CFLAGS = DEVICE + AFLAGS = CFLAGS + LFLAGS = ARCH_ABI + ' --specs=nano.specs --specs=nosys.specs -u _printf_float -u _scanf_float -nostartfiles -Wl,--gc-sections ' + + CPATH = '' + LPATH = '' + + if BUILD == 'ram_debug': + CFLAGS += ' -gdwarf-2' + AFLAGS += ' -gdwarf-2' + CFLAGS += ' -O0' + LFLAGS += ' -O0' + LINKER_FILE = 'board/linker_scripts/ram_rtt.ld' + elif BUILD == 'ram_release': + CFLAGS += ' -O2' + LFLAGS += ' -O2' + LINKER_FILE = 'board/linker_scripts/ram_rtt.ld' + elif BUILD == 'flash_debug': + CFLAGS += ' -gdwarf-2' + AFLAGS += ' -gdwarf-2' + CFLAGS += ' -O0' + LFLAGS += ' -O0' + CFLAGS += ' -DFLASH_XIP=1' + LINKER_FILE = 'board/linker_scripts/flash_rtt.ld' + elif BUILD == 'flash_release': + CFLAGS += ' -O2' + LFLAGS += ' -O2' + CFLAGS += ' -DFLASH_XIP=1' + LINKER_FILE = 'board/linker_scripts/flash_rtt.ld' + else: + CFLAGS += ' -O2' + LFLAGS += ' -O2' + LINKER_FILE = 'board/linker_scripts/flash_rtt.ld' + LFLAGS += ' -T ' + LINKER_FILE + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + + # module setting + CXXFLAGS = CFLAGS + ' -Woverloaded-virtual -fno-exceptions -fno-rtti ' + CFLAGS = CFLAGS + ' -std=gnu11' diff --git a/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/SConscript b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/SConscript new file mode 100644 index 0000000000..a1ec2c8e79 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/SConscript @@ -0,0 +1,19 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() + +# add the startup files + +src = Glob('*.c') + +if rtconfig.PLATFORM == 'gcc': + src += [os.path.join('toolchains', 'gcc', 'start.S')] + src += [os.path.join('toolchains', 'gcc', 'port_gcc.S')] + +CPPPATH = [cwd] +CPPDEFINES=['D45', rtconfig.CHIP_NAME] + +group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/startup.c b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/startup.c new file mode 100644 index 0000000000..1831ade775 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/startup.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2021-2024 HPMicro + * + * + */ + +#include "hpm_common.h" +#include "hpm_soc.h" +#include "hpm_l1c_drv.h" +#include + +void system_init(void); + +extern int entry(void); + +extern void __libc_init_array(void); +extern void __libc_fini_array(void); + +void system_init(void) +{ + disable_global_irq(CSR_MSTATUS_MIE_MASK); + disable_irq_from_intc(); + enable_irq_from_intc(); + enable_global_irq(CSR_MSTATUS_MIE_MASK); +#ifndef CONFIG_NOT_ENABLE_ICACHE + l1c_ic_enable(); +#endif +#ifndef CONFIG_NOT_ENABLE_DCACHE + l1c_dc_enable(); +#endif +} + +__attribute__((weak)) void c_startup(void) +{ + uint32_t i, size; +#ifdef FLASH_XIP + extern uint8_t __vector_ram_start__[], __vector_ram_end__[], __vector_load_addr__[]; + size = __vector_ram_end__ - __vector_ram_start__; + for (i = 0; i < size; i++) { + *(__vector_ram_start__ + i) = *(__vector_load_addr__ + i); + } +#endif + + extern uint8_t __etext[]; + extern uint8_t __bss_start__[], __bss_end__[]; + extern uint8_t __tbss_start__[], __tbss_end__[]; + extern uint8_t __tdata_start__[], __tdata_end__[]; + extern uint8_t __data_start__[], __data_end__[]; + extern uint8_t __noncacheable_bss_start__[], __noncacheable_bss_end__[]; + extern uint8_t __ramfunc_start__[], __ramfunc_end__[]; + extern uint8_t __noncacheable_init_start__[], __noncacheable_init_end__[]; + + /* tbss section */ + size = __tbss_end__ - __tbss_start__; + for (i = 0; i < size; i++) { + *(__tbss_start__ + i) = 0; + } + + /* bss section */ + size = __bss_end__ - __bss_start__; + for (i = 0; i < size; i++) { + *(__bss_start__ + i) = 0; + } + + /* noncacheable bss section */ + size = __noncacheable_bss_end__ - __noncacheable_bss_start__; + for (i = 0; i < size; i++) { + *(__noncacheable_bss_start__ + i) = 0; + } + + /* tdata section LMA: etext */ + size = __tdata_end__ - __tdata_start__; + for (i = 0; i < size; i++) { + *(__tdata_start__ + i) = *(__etext + i); + } + + /* data section LMA: etext */ + size = __data_end__ - __data_start__; + for (i = 0; i < size; i++) { + *(__data_start__ + i) = *(__etext + (__tdata_end__ - __tdata_start__) + i); + } + + /* ramfunc section LMA: etext + data length */ + size = __ramfunc_end__ - __ramfunc_start__; + for (i = 0; i < size; i++) { + *(__ramfunc_start__ + i) = *(__etext + (__data_end__ - __tdata_start__) + i); + } + + /* noncacheable init section LMA: etext + data length + ramfunc length */ + size = __noncacheable_init_end__ - __noncacheable_init_start__; + for (i = 0; i < size; i++) { + *(__noncacheable_init_start__ + i) = *(__etext + (__data_end__ - __tdata_start__) + (__ramfunc_end__ - __ramfunc_start__) + i); + } +} + +__attribute__((weak)) int main(void) +{ + while(1); +} + +void reset_handler(void) +{ + /** + * Disable preemptive interrupt + */ + HPM_PLIC->FEATURE = 0; + /* + * Initialize LMA/VMA sections. + * Relocation for any sections that need to be copied from LMA to VMA. + */ + c_startup(); + + /* Call platform specific hardware initialization */ + system_init(); + + /* Do global constructors */ + __libc_init_array(); + + + + /* Entry function */ + entry(); +} + + +__attribute__((weak)) void _init() +{ +} diff --git a/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/port_gcc.S b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/port_gcc.S new file mode 100644 index 0000000000..2708b48e45 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/port_gcc.S @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021-2023 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#include "cpuport.h" + + .globl rt_hw_do_after_save_above + .type rt_hw_do_after_save_above,@function +rt_hw_do_after_save_above: + addi sp, sp, -4 + STORE ra, 0 * REGBYTES(sp) + + csrr t1, mcause + andi t1, t1, 0x3FF + /* get ISR */ + la t2, trap_entry + jalr t2 + + LOAD ra, 0 * REGBYTES(sp) + addi sp, sp, 4 + ret diff --git a/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/start.S b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/start.S new file mode 100644 index 0000000000..63433e71ae --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/start.S @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021-2023 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + #include + #include "hpm_csr_regs.h" + .section .start, "ax" + + .global _start + .type _start,@function + +_start: + /* Initialize global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + la tp, __thread_pointer + .option pop + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, CSR_MSTATUS_FS_MASK + csrrs t0, mstatus, t0 + + /* Initialize FCSR */ + fscsr zero +#endif + +#ifdef INIT_EXT_RAM_FOR_DATA + la t0, _stack_in_dlm + mv sp, t0 + call _init_ext_ram +#endif + + /* Initialize stack pointer */ + la t0, _stack + mv sp, t0 + +#ifdef __nds_execit + /* Initialize EXEC.IT table */ + la t0, _ITB_BASE_ + csrw uitb, t0 +#endif + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, CSR_MSTATUS_FS_MASK + csrrs t0, mstatus, t0 + + /* Initialize FCSR */ + fscsr zero +#endif + +#ifdef HPM_USING_VECTOR_PREEMPTED_MODE + /* Initial machine trap-vector Base */ + la t0, __vector_table + csrw mtvec, t0 + /* Enable vectored external PLIC interrupt */ + csrsi CSR_MMISC_CTL, 2 +#else + /* Initial machine trap-vector Base */ + la t0, SW_handler + csrw mtvec, t0 + /* Disable vectored external PLIC interrupt */ + csrci CSR_MMISC_CTL, 2 +#endif + + /* System reset handler */ + call reset_handler + + /* Infinite loop, if returned accidently */ +1: j 1b + + .weak nmi_handler +nmi_handler: +1: j 1b + + .global default_irq_handler + .weak default_irq_handler + .align 2 +default_irq_handler: +1: j 1b + + .macro IRQ_HANDLER irq + .weak default_isr_\irq + .set default_isr_\irq, default_irq_handler + .long default_isr_\irq + .endm + +#include "vectors.S" diff --git a/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/vectors.S b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/vectors.S new file mode 100644 index 0000000000..cc6604ec3b --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/toolchains/gcc/vectors.S @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2021-2024 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + .section .vector_table, "a" + .global __vector_table + .align 9 +__vector_table: + .weak default_isr_trap + .set default_isr_trap, SW_handler + .long default_isr_trap + IRQ_HANDLER 1 /* GPIO0_A IRQ handler */ + IRQ_HANDLER 2 /* GPIO0_B IRQ handler */ + IRQ_HANDLER 3 /* GPIO0_C IRQ handler */ + IRQ_HANDLER 4 /* GPIO0_D IRQ handler */ + IRQ_HANDLER 5 /* GPIO0_E IRQ handler */ + IRQ_HANDLER 6 /* GPIO0_F IRQ handler */ + IRQ_HANDLER 7 /* GPIO0_V IRQ handler */ + IRQ_HANDLER 8 /* GPIO0_W IRQ handler */ + IRQ_HANDLER 9 /* GPIO0_X IRQ handler */ + IRQ_HANDLER 10 /* GPIO0_Y IRQ handler */ + IRQ_HANDLER 11 /* GPIO0_Z IRQ handler */ + IRQ_HANDLER 12 /* GPIO1_A IRQ handler */ + IRQ_HANDLER 13 /* GPIO1_B IRQ handler */ + IRQ_HANDLER 14 /* GPIO1_C IRQ handler */ + IRQ_HANDLER 15 /* GPIO1_D IRQ handler */ + IRQ_HANDLER 16 /* GPIO1_E IRQ handler */ + IRQ_HANDLER 17 /* GPIO1_F IRQ handler */ + IRQ_HANDLER 18 /* GPIO1_V IRQ handler */ + IRQ_HANDLER 19 /* GPIO1_W IRQ handler */ + IRQ_HANDLER 20 /* GPIO1_X IRQ handler */ + IRQ_HANDLER 21 /* GPIO1_Y IRQ handler */ + IRQ_HANDLER 22 /* GPIO1_Z IRQ handler */ + IRQ_HANDLER 23 /* GPTMR0 IRQ handler */ + IRQ_HANDLER 24 /* GPTMR1 IRQ handler */ + IRQ_HANDLER 25 /* GPTMR2 IRQ handler */ + IRQ_HANDLER 26 /* GPTMR3 IRQ handler */ + IRQ_HANDLER 27 /* GPTMR4 IRQ handler */ + IRQ_HANDLER 28 /* GPTMR5 IRQ handler */ + IRQ_HANDLER 29 /* GPTMR6 IRQ handler */ + IRQ_HANDLER 30 /* GPTMR7 IRQ handler */ + IRQ_HANDLER 31 /* UART0 IRQ handler */ + IRQ_HANDLER 32 /* UART1 IRQ handler */ + IRQ_HANDLER 33 /* UART2 IRQ handler */ + IRQ_HANDLER 34 /* UART3 IRQ handler */ + IRQ_HANDLER 35 /* UART4 IRQ handler */ + IRQ_HANDLER 36 /* UART5 IRQ handler */ + IRQ_HANDLER 37 /* UART6 IRQ handler */ + IRQ_HANDLER 38 /* UART7 IRQ handler */ + IRQ_HANDLER 39 /* I2C0 IRQ handler */ + IRQ_HANDLER 40 /* I2C1 IRQ handler */ + IRQ_HANDLER 41 /* I2C2 IRQ handler */ + IRQ_HANDLER 42 /* I2C3 IRQ handler */ + IRQ_HANDLER 43 /* SPI0 IRQ handler */ + IRQ_HANDLER 44 /* SPI1 IRQ handler */ + IRQ_HANDLER 45 /* SPI2 IRQ handler */ + IRQ_HANDLER 46 /* SPI3 IRQ handler */ + IRQ_HANDLER 47 /* TSNS IRQ handler */ + IRQ_HANDLER 48 /* MBX0A IRQ handler */ + IRQ_HANDLER 49 /* MBX0B IRQ handler */ + IRQ_HANDLER 50 /* MBX1A IRQ handler */ + IRQ_HANDLER 51 /* MBX1B IRQ handler */ + IRQ_HANDLER 52 /* EWDG0 IRQ handler */ + IRQ_HANDLER 53 /* EWDG1 IRQ handler */ + IRQ_HANDLER 54 /* EWDG2 IRQ handler */ + IRQ_HANDLER 55 /* EWDG3 IRQ handler */ + IRQ_HANDLER 56 /* HDMA IRQ handler */ + IRQ_HANDLER 57 /* LOBS IRQ handler */ + IRQ_HANDLER 58 /* ADC0 IRQ handler */ + IRQ_HANDLER 59 /* ADC1 IRQ handler */ + IRQ_HANDLER 60 /* ADC2 IRQ handler */ + IRQ_HANDLER 61 /* ADC3 IRQ handler */ + IRQ_HANDLER 62 /* ACMP0[0] IRQ handler */ + IRQ_HANDLER 63 /* ACMP0[1] IRQ handler */ + IRQ_HANDLER 64 /* ACMP1[0] IRQ handler */ + IRQ_HANDLER 65 /* ACMP1[1] IRQ handler */ + IRQ_HANDLER 66 /* ACMP2[0] IRQ handler */ + IRQ_HANDLER 67 /* ACMP2[1] IRQ handler */ + IRQ_HANDLER 68 /* ACMP3[0] IRQ handler */ + IRQ_HANDLER 69 /* ACMP3[1] IRQ handler */ + IRQ_HANDLER 70 /* I2S0 IRQ handler */ + IRQ_HANDLER 71 /* I2S1 IRQ handler */ + IRQ_HANDLER 72 /* DAO IRQ handler */ + IRQ_HANDLER 73 /* PDM IRQ handler */ + IRQ_HANDLER 74 /* UART8 IRQ handler */ + IRQ_HANDLER 75 /* UART9 IRQ handler */ + IRQ_HANDLER 76 /* UART10 IRQ handler */ + IRQ_HANDLER 77 /* UART11 IRQ handler */ + IRQ_HANDLER 78 /* UART12 IRQ handler */ + IRQ_HANDLER 79 /* UART13 IRQ handler */ + IRQ_HANDLER 80 /* UART14 IRQ handler */ + IRQ_HANDLER 81 /* UART15 IRQ handler */ + IRQ_HANDLER 82 /* I2C4 IRQ handler */ + IRQ_HANDLER 83 /* I2C5 IRQ handler */ + IRQ_HANDLER 84 /* I2C6 IRQ handler */ + IRQ_HANDLER 85 /* I2C7 IRQ handler */ + IRQ_HANDLER 86 /* SPI4 IRQ handler */ + IRQ_HANDLER 87 /* SPI5 IRQ handler */ + IRQ_HANDLER 88 /* SPI6 IRQ handler */ + IRQ_HANDLER 89 /* SPI7 IRQ handler */ + IRQ_HANDLER 90 /* MCAN0 IRQ handler */ + IRQ_HANDLER 91 /* MCAN1 IRQ handler */ + IRQ_HANDLER 92 /* MCAN2 IRQ handler */ + IRQ_HANDLER 93 /* MCAN3 IRQ handler */ + IRQ_HANDLER 94 /* MCAN4 IRQ handler */ + IRQ_HANDLER 95 /* MCAN5 IRQ handler */ + IRQ_HANDLER 96 /* MCAN6 IRQ handler */ + IRQ_HANDLER 97 /* MCAN7 IRQ handler */ + IRQ_HANDLER 98 /* PTPC IRQ handler */ + IRQ_HANDLER 99 /* QEI0 IRQ handler */ + IRQ_HANDLER 100 /* QEI1 IRQ handler */ + IRQ_HANDLER 101 /* QEI2 IRQ handler */ + IRQ_HANDLER 102 /* QEI3 IRQ handler */ + IRQ_HANDLER 103 /* PWM0 IRQ handler */ + IRQ_HANDLER 104 /* PWM1 IRQ handler */ + IRQ_HANDLER 105 /* PWM2 IRQ handler */ + IRQ_HANDLER 106 /* PWM3 IRQ handler */ + IRQ_HANDLER 107 /* RDC0 IRQ handler */ + IRQ_HANDLER 108 /* RDC1 IRQ handler */ + IRQ_HANDLER 109 /* SDM0 IRQ handler */ + IRQ_HANDLER 110 /* SDM1 IRQ handler */ + IRQ_HANDLER 111 /* SEI[0] IRQ handler */ + IRQ_HANDLER 112 /* SEI[1] IRQ handler */ + IRQ_HANDLER 113 /* SEI[2] IRQ handler */ + IRQ_HANDLER 114 /* SEI[3] IRQ handler */ + IRQ_HANDLER 115 /* MTG0 IRQ handler */ + IRQ_HANDLER 116 /* MTG1 IRQ handler */ + IRQ_HANDLER 117 /* VSC0 IRQ handler */ + IRQ_HANDLER 118 /* VSC1 IRQ handler */ + IRQ_HANDLER 119 /* CLC0[0] IRQ handler */ + IRQ_HANDLER 120 /* CLC0[1] IRQ handler */ + IRQ_HANDLER 121 /* CLC1[0] IRQ handler */ + IRQ_HANDLER 122 /* CLC1[1] IRQ handler */ + IRQ_HANDLER 123 /* TRGMUX0 IRQ handler */ + IRQ_HANDLER 124 /* TRGMUX1 IRQ handler */ + IRQ_HANDLER 125 /* ENET0 IRQ handler */ + IRQ_HANDLER 126 /* NTMR0 IRQ handler */ + IRQ_HANDLER 127 /* USB0 IRQ handler */ + IRQ_HANDLER 128 /* TSW[0] IRQ handler */ + IRQ_HANDLER 129 /* TSW[1] IRQ handler */ + IRQ_HANDLER 130 /* TSW[2] IRQ handler */ + IRQ_HANDLER 131 /* TSW[3] IRQ handler */ + IRQ_HANDLER 132 /* TSW_PTP_EVT IRQ handler */ + IRQ_HANDLER 133 /* ESC IRQ handler */ + IRQ_HANDLER 134 /* ESC_SYNC0 IRQ handler */ + IRQ_HANDLER 135 /* ESC_SYNC1 IRQ handler */ + IRQ_HANDLER 136 /* ESC_RESET IRQ handler */ + IRQ_HANDLER 137 /* XPI0 IRQ handler */ + IRQ_HANDLER 138 /* FEMC IRQ handler */ + IRQ_HANDLER 139 /* PPI IRQ handler */ + IRQ_HANDLER 140 /* XDMA IRQ handler */ + IRQ_HANDLER 141 /* FFA IRQ handler */ + IRQ_HANDLER 142 /* SDP IRQ handler */ + IRQ_HANDLER 143 /* RNG IRQ handler */ + IRQ_HANDLER 144 /* PKA IRQ handler */ + IRQ_HANDLER 145 /* PSEC IRQ handler */ + IRQ_HANDLER 146 /* PGPIO IRQ handler */ + IRQ_HANDLER 147 /* PEWDG IRQ handler */ + IRQ_HANDLER 148 /* PTMR IRQ handler */ + IRQ_HANDLER 149 /* PUART IRQ handler */ + IRQ_HANDLER 150 /* FUSE IRQ handler */ + IRQ_HANDLER 151 /* SECMON IRQ handler */ + IRQ_HANDLER 152 /* RTC IRQ handler */ + IRQ_HANDLER 153 /* PAD_WAKEUP IRQ handler */ + IRQ_HANDLER 154 /* BGPIO IRQ handler */ + IRQ_HANDLER 155 /* BVIO IRQ handler */ + IRQ_HANDLER 156 /* BROWNOUT IRQ handler */ + IRQ_HANDLER 157 /* SYSCTL IRQ handler */ + IRQ_HANDLER 158 /* CPU0 IRQ handler */ + IRQ_HANDLER 159 /* CPU1 IRQ handler */ + IRQ_HANDLER 160 /* DEBUG0 IRQ handler */ + IRQ_HANDLER 161 /* DEBUG1 IRQ handler */ \ No newline at end of file diff --git a/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/trap.c b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/trap.c new file mode 100644 index 0000000000..470b3fe266 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/startup/HPM6E80/trap.c @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2021-2024 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#include "hpm_common.h" +#include "hpm_soc.h" +#include +#include "rt_hw_stack_frame.h" + +#define MCAUSE_INSTR_ADDR_MISALIGNED (0U) //!< Instruction Address misaligned +#define MCAUSE_INSTR_ACCESS_FAULT (1U) //!< Instruction access fault +#define MCAUSE_ILLEGAL_INSTR (2U) //!< Illegal instruction +#define MCAUSE_BREAKPOINT (3U) //!< Breakpoint +#define MCAUSE_LOAD_ADDR_MISALIGNED (4U) //!< Load address misaligned +#define MCAUSE_LOAD_ACCESS_FAULT (5U) //!< Load access fault +#define MCAUSE_STORE_AMO_ADDR_MISALIGNED (6U) //!< Store/AMO address misaligned +#define MCAUSE_STORE_AMO_ACCESS_FAULT (7U) //!< Store/AMO access fault +#define MCAUSE_ECALL_FROM_USER_MODE (8U) //!< Environment call from User mode +#define MCAUSE_ECALL_FROM_SUPERVISOR_MODE (9U) //!< Environment call from Supervisor mode +#define MCAUSE_ECALL_FROM_MACHINE_MODE (11U) //!< Environment call from machine mode +#define MCAUSE_INSTR_PAGE_FAULT (12U) //!< Instruction page fault +#define MCAUSE_LOAD_PAGE_FAULT (13) //!< Load page fault +#define MCAUSE_STORE_AMO_PAGE_FAULT (15U) //!< Store/AMO page fault + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + +#ifdef DEBUG +#define RT_EXCEPTION_TRACE rt_kprintf +#else +#define RT_EXCEPTION_TRACE(...) +#endif + +typedef void (*isr_func_t)(void); + +static volatile rt_hw_stack_frame_t *s_stack_frame; + +__attribute((weak)) void mchtmr_isr(void) +{ +} + +__attribute__((weak)) void mswi_isr(void) +{ +} + +__attribute__((weak)) void syscall_handler(uint32_t n, uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3) +{ +} + +void rt_show_stack_frame(void) +{ + RT_EXCEPTION_TRACE("Stack frame:\r\n----------------------------------------\r\n"); + RT_EXCEPTION_TRACE("ra : 0x%08x\r\n", s_stack_frame->ra); + RT_EXCEPTION_TRACE("mstatus : 0x%08x\r\n", read_csr(0x300));//mstatus + RT_EXCEPTION_TRACE("t0 : 0x%08x\r\n", s_stack_frame->t0); + RT_EXCEPTION_TRACE("t1 : 0x%08x\r\n", s_stack_frame->t1); + RT_EXCEPTION_TRACE("t2 : 0x%08x\r\n", s_stack_frame->t2); + RT_EXCEPTION_TRACE("a0 : 0x%08x\r\n", s_stack_frame->a0); + RT_EXCEPTION_TRACE("a1 : 0x%08x\r\n", s_stack_frame->a1); + RT_EXCEPTION_TRACE("a2 : 0x%08x\r\n", s_stack_frame->a2); + RT_EXCEPTION_TRACE("a3 : 0x%08x\r\n", s_stack_frame->a3); + RT_EXCEPTION_TRACE("a4 : 0x%08x\r\n", s_stack_frame->a4); + RT_EXCEPTION_TRACE("a5 : 0x%08x\r\n", s_stack_frame->a5); +#ifndef __riscv_32e + RT_EXCEPTION_TRACE("a6 : 0x%08x\r\n", s_stack_frame->a6); + RT_EXCEPTION_TRACE("a7 : 0x%08x\r\n", s_stack_frame->a7); + RT_EXCEPTION_TRACE("t3 : 0x%08x\r\n", s_stack_frame->t3); + RT_EXCEPTION_TRACE("t4 : 0x%08x\r\n", s_stack_frame->t4); + RT_EXCEPTION_TRACE("t5 : 0x%08x\r\n", s_stack_frame->t5); + RT_EXCEPTION_TRACE("t6 : 0x%08x\r\n", s_stack_frame->t6); +#endif +} + +uint32_t exception_handler(uint32_t cause, uint32_t epc) +{ + /* Unhandled Trap */ + uint32_t mdcause = read_csr(CSR_MDCAUSE); + uint32_t mtval = read_csr(CSR_MTVAL); + rt_uint32_t mscratch = read_csr(0x340); + + s_stack_frame = (rt_hw_stack_frame_t *)mscratch; + rt_show_stack_frame(); + + switch (cause) + { + case MCAUSE_INSTR_ADDR_MISALIGNED: + RT_EXCEPTION_TRACE("exception: instruction address was mis-aligned, mtval=0x%08x\n", mtval); + break; + case MCAUSE_INSTR_ACCESS_FAULT: + RT_EXCEPTION_TRACE("exception: instruction access fault happened, mtval=0x%08x, epc=0x%08x\n", mtval, epc); + switch (mdcause & 0x07) + { + case 1: + RT_EXCEPTION_TRACE("mdcause: ECC/Parity error\r\n"); + break; + case 2: + RT_EXCEPTION_TRACE("mdcause: PMP instruction access violation \r\n"); + break; + case 3: + RT_EXCEPTION_TRACE("mdcause: BUS error\r\n"); + break; + case 4: + RT_EXCEPTION_TRACE("mdcause: PMP empty hole access \r\n"); + break; + default: + RT_EXCEPTION_TRACE("mdcause: reserved \r\n"); + break; + } + break; + case MCAUSE_ILLEGAL_INSTR: + RT_EXCEPTION_TRACE("exception: illegal instruction was met, mtval=0x%08x\n", mtval); + switch (mdcause & 0x07) + { + case 0: + RT_EXCEPTION_TRACE("mdcause: the actual faulting instruction is stored in the mtval CSR\r\n"); + break; + case 1: + RT_EXCEPTION_TRACE("mdcause: FP disabled exception \r\n"); + break; + case 2: + RT_EXCEPTION_TRACE("mdcause: ACE disabled exception \r\n"); + break; + default: + RT_EXCEPTION_TRACE("mdcause: reserved \r\n"); + break; + } + break; + case MCAUSE_BREAKPOINT: + RT_EXCEPTION_TRACE("exception: breakpoint was hit, mtval=0x%08x\n", mtval); + break; + case MCAUSE_LOAD_ADDR_MISALIGNED: + RT_EXCEPTION_TRACE("exception: load address was mis-aligned, mtval=0x%08x\n", mtval); + break; + case MCAUSE_LOAD_ACCESS_FAULT: + RT_EXCEPTION_TRACE("exception: load access fault happened, epc=%08x, mdcause=0x%x\n", epc, mdcause); + switch (mdcause & 0x07) + { + case 1: + RT_EXCEPTION_TRACE("mdcause: ECC/Parity error\r\n"); + break; + case 2: + RT_EXCEPTION_TRACE("mdcause: PMP instruction access violation \r\n"); + break; + case 3: + RT_EXCEPTION_TRACE("mdcause: BUS error\r\n"); + break; + case 4: + RT_EXCEPTION_TRACE("mdcause: Misaligned access \r\n"); + break; + case 5: + RT_EXCEPTION_TRACE("mdcause: PMP empty hole access \r\n"); + break; + case 6: + RT_EXCEPTION_TRACE("mdcause: PMA attribute inconsistency\r\n"); + break; + default: + RT_EXCEPTION_TRACE("mdcause: reserved \r\n"); + break; + } + break; + case MCAUSE_STORE_AMO_ADDR_MISALIGNED: + RT_EXCEPTION_TRACE("exception: store amo address was misaligned, epc=%08x\n", epc); + break; + case MCAUSE_STORE_AMO_ACCESS_FAULT: + RT_EXCEPTION_TRACE("exception: store amo access fault happened, epc=%08x\n", epc); + switch (mdcause & 0x07) + { + case 1: + RT_EXCEPTION_TRACE("mdcause: ECC/Parity error\r\n"); + break; + case 2: + RT_EXCEPTION_TRACE("mdcause: PMP instruction access violation \r\n"); + break; + case 3: + RT_EXCEPTION_TRACE("mdcause: BUS error\r\n"); + break; + case 4: + RT_EXCEPTION_TRACE("mdcause: Misaligned access \r\n"); + break; + case 5: + RT_EXCEPTION_TRACE("mdcause: PMP empty hole access \r\n"); + break; + case 6: + RT_EXCEPTION_TRACE("mdcause: PMA attribute inconsistency\r\n"); + break; + case 7: + RT_EXCEPTION_TRACE("mdcause: PMA NAMO exception \r\n"); + default: + RT_EXCEPTION_TRACE("mdcause: reserved \r\n"); + break; + } + break; + default: + RT_EXCEPTION_TRACE("Unknown exception happened, cause=%d\n", cause); + break; + } + + rt_kprintf("cause=0x%08x, epc=0x%08x, ra=0x%08x\n", cause, epc, s_stack_frame->ra); + while(1) { + } +} + +void trap_entry(void); + +void trap_entry(void) +{ + uint32_t mcause = read_csr(CSR_MCAUSE); + uint32_t mepc = read_csr(CSR_MEPC); + uint32_t mstatus = read_csr(CSR_MSTATUS); + +#if SUPPORT_PFT_ARCH + uint32_t mxstatus = read_csr(CSR_MXSTATUS); +#endif +#ifdef __riscv_dsp + int ucode = read_csr(CSR_UCODE); +#endif +#ifdef __riscv_flen + int fcsr = read_fcsr(); +#endif + + /* clobbers list for ecall */ +#ifdef __riscv_32e + __asm volatile("" : : :"t0", "a0", "a1", "a2", "a3"); +#else + __asm volatile("" : : :"a7", "a0", "a1", "a2", "a3"); +#endif + + /* Do your trap handling */ + uint32_t cause_type = mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK; + uint32_t irq_index; + if (mcause & CSR_MCAUSE_INTERRUPT_MASK) + { + switch (cause_type) + { + /* Machine timer interrupt */ + case IRQ_M_TIMER: + mchtmr_isr(); + break; + /* Machine EXT interrupt */ + case IRQ_M_EXT: + /* Claim interrupt */ + irq_index = __plic_claim_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE); + /* Execute EXT interrupt handler */ + if (irq_index > 0) + { + ((isr_func_t) __vector_table[irq_index])(); + /* Complete interrupt */ + __plic_complete_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE, irq_index); + } + break; + /* Machine SWI interrupt */ + case IRQ_M_SOFT: + mswi_isr(); + intc_m_complete_swi(); + break; + } + } + else if (cause_type == MCAUSE_ECALL_FROM_MACHINE_MODE) + { + /* Machine Syscal call */ + __asm volatile( + "mv a4, a3\n" + "mv a3, a2\n" + "mv a2, a1\n" + "mv a1, a0\n" +#ifdef __riscv_32e + "mv a0, t0\n" +#else + "mv a0, a7\n" +#endif + "call syscall_handler\n" + : : : "a4" + ); + mepc += 4; + } + else + { + mepc = exception_handler(mcause, mepc); + } + + /* Restore CSR */ + write_csr(CSR_MSTATUS, mstatus); + write_csr(CSR_MEPC, mepc); +#if SUPPORT_PFT_ARCH + write_csr(CSR_MXSTATUS, mxstatus); +#endif +#ifdef __riscv_dsp + write_csr(CSR_UCODE, ucode); +#endif +#ifdef __riscv_flen + write_fcsr(fcsr); +#endif +} + +/** + * Trap Handler + */ +rt_weak void handle_trap(rt_uint32_t mcause, rt_uint32_t mepc, rt_uint32_t sp) +{ +} \ No newline at end of file diff --git a/bsp/hpmicro/hpm6e00evk/startup/SConscript b/bsp/hpmicro/hpm6e00evk/startup/SConscript new file mode 100644 index 0000000000..de51a7c0d6 --- /dev/null +++ b/bsp/hpmicro/hpm6e00evk/startup/SConscript @@ -0,0 +1,13 @@ +# for module compiling +import os +Import('rtconfig') +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] + +objs = objs + SConscript(os.path.join(cwd, rtconfig.CHIP_NAME, 'SConscript')) +ASFLAGS = ' -I' + cwd + +Return('objs') \ No newline at end of file