From dc5412d208b0c5a9f813f8180fc5407f410b82b1 Mon Sep 17 00:00:00 2001 From: rcitach Date: Mon, 20 Apr 2026 08:14:13 +0000 Subject: [PATCH 1/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20rdk=20s100=20bsp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/rdk/s100/.config | 1450 ++++++++++++++++++++++++++ bsp/rdk/s100/Kconfig | 37 + bsp/rdk/s100/README.md | 154 +++ bsp/rdk/s100/SConscript | 14 + bsp/rdk/s100/SConstruct | 32 + bsp/rdk/s100/applications/SConscript | 9 + bsp/rdk/s100/applications/main.c | 16 + bsp/rdk/s100/board/SConscript | 10 + bsp/rdk/s100/board/board.c | 31 + bsp/rdk/s100/board/board.h | 98 ++ bsp/rdk/s100/board/rsc_table.c | 73 ++ bsp/rdk/s100/board/rsc_table.h | 89 ++ bsp/rdk/s100/drivers/Kconfig | 111 ++ bsp/rdk/s100/drivers/SConscript | 22 + bsp/rdk/s100/drivers/drv_can.c | 1313 +++++++++++++++++++++++ bsp/rdk/s100/drivers/drv_can.h | 1223 ++++++++++++++++++++++ bsp/rdk/s100/drivers/drv_gpio.c | 494 +++++++++ bsp/rdk/s100/drivers/drv_gpio.h | 30 + bsp/rdk/s100/drivers/drv_pinmux.c | 147 +++ bsp/rdk/s100/drivers/drv_pinmux.h | 37 + bsp/rdk/s100/drivers/drv_timer.c | 92 ++ bsp/rdk/s100/drivers/drv_uart_v2.c | 522 ++++++++++ bsp/rdk/s100/link.lds | 233 +++++ bsp/rdk/s100/rtconfig.h | 428 ++++++++ bsp/rdk/s100/rtconfig.py | 83 ++ bsp/rdk/s100/startup/SConscript | 13 + bsp/rdk/s100/startup/armv8.h | 80 ++ bsp/rdk/s100/startup/backtrace.c | 545 ++++++++++ bsp/rdk/s100/startup/backtrace.h | 83 ++ bsp/rdk/s100/startup/context_gcc.S | 248 +++++ bsp/rdk/s100/startup/cp15.h | 29 + bsp/rdk/s100/startup/cp15_gcc.S | 167 +++ bsp/rdk/s100/startup/cpuport.c | 58 ++ bsp/rdk/s100/startup/cpuport.h | 89 ++ bsp/rdk/s100/startup/gicv3.c | 830 +++++++++++++++ bsp/rdk/s100/startup/gicv3.h | 197 ++++ bsp/rdk/s100/startup/interrupt.c | 281 +++++ bsp/rdk/s100/startup/interrupt.h | 54 + bsp/rdk/s100/startup/stack.c | 71 ++ bsp/rdk/s100/startup/startup_gcc.S | 476 +++++++++ bsp/rdk/s100/startup/system.c | 135 +++ bsp/rdk/s100/startup/trap.c | 342 ++++++ bsp/rdk/s100/startup/vector_gcc.S | 169 +++ 43 files changed, 10615 insertions(+) create mode 100644 bsp/rdk/s100/.config create mode 100644 bsp/rdk/s100/Kconfig create mode 100644 bsp/rdk/s100/README.md create mode 100644 bsp/rdk/s100/SConscript create mode 100644 bsp/rdk/s100/SConstruct create mode 100644 bsp/rdk/s100/applications/SConscript create mode 100644 bsp/rdk/s100/applications/main.c create mode 100644 bsp/rdk/s100/board/SConscript create mode 100644 bsp/rdk/s100/board/board.c create mode 100644 bsp/rdk/s100/board/board.h create mode 100644 bsp/rdk/s100/board/rsc_table.c create mode 100644 bsp/rdk/s100/board/rsc_table.h create mode 100644 bsp/rdk/s100/drivers/Kconfig create mode 100644 bsp/rdk/s100/drivers/SConscript create mode 100644 bsp/rdk/s100/drivers/drv_can.c create mode 100644 bsp/rdk/s100/drivers/drv_can.h create mode 100644 bsp/rdk/s100/drivers/drv_gpio.c create mode 100644 bsp/rdk/s100/drivers/drv_gpio.h create mode 100644 bsp/rdk/s100/drivers/drv_pinmux.c create mode 100644 bsp/rdk/s100/drivers/drv_pinmux.h create mode 100644 bsp/rdk/s100/drivers/drv_timer.c create mode 100644 bsp/rdk/s100/drivers/drv_uart_v2.c create mode 100644 bsp/rdk/s100/link.lds create mode 100644 bsp/rdk/s100/rtconfig.h create mode 100644 bsp/rdk/s100/rtconfig.py create mode 100644 bsp/rdk/s100/startup/SConscript create mode 100644 bsp/rdk/s100/startup/armv8.h create mode 100644 bsp/rdk/s100/startup/backtrace.c create mode 100644 bsp/rdk/s100/startup/backtrace.h create mode 100644 bsp/rdk/s100/startup/context_gcc.S create mode 100644 bsp/rdk/s100/startup/cp15.h create mode 100644 bsp/rdk/s100/startup/cp15_gcc.S create mode 100644 bsp/rdk/s100/startup/cpuport.c create mode 100644 bsp/rdk/s100/startup/cpuport.h create mode 100644 bsp/rdk/s100/startup/gicv3.c create mode 100644 bsp/rdk/s100/startup/gicv3.h create mode 100644 bsp/rdk/s100/startup/interrupt.c create mode 100644 bsp/rdk/s100/startup/interrupt.h create mode 100644 bsp/rdk/s100/startup/stack.c create mode 100644 bsp/rdk/s100/startup/startup_gcc.S create mode 100644 bsp/rdk/s100/startup/system.c create mode 100644 bsp/rdk/s100/startup/trap.c create mode 100644 bsp/rdk/s100/startup/vector_gcc.S diff --git a/bsp/rdk/s100/.config b/bsp/rdk/s100/.config new file mode 100644 index 00000000000..561ed624e0c --- /dev/null +++ b/bsp/rdk/s100/.config @@ -0,0 +1,1450 @@ +CONFIG_SOC_S100=y + +# +# S100 BSP Options +# +CONFIG_RT_USING_FPU=y +# end of S100 BSP Options + +# +# RT-Thread Kernel +# + +# +# klibc options +# + +# +# rt_vsnprintf options +# +# CONFIG_RT_KLIBC_USING_LIBC_VSNPRINTF is not set +# CONFIG_RT_KLIBC_USING_VSNPRINTF_LONGLONG is not set +# CONFIG_RT_KLIBC_USING_VSNPRINTF_STANDARD is not set +# end of rt_vsnprintf options + +# +# rt_vsscanf options +# +# CONFIG_RT_KLIBC_USING_LIBC_VSSCANF is not set +# end of rt_vsscanf options + +# +# rt_memset options +# +# CONFIG_RT_KLIBC_USING_USER_MEMSET is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMSET is not set +# CONFIG_RT_KLIBC_USING_TINY_MEMSET is not set +# end of rt_memset options + +# +# rt_memcpy options +# +# CONFIG_RT_KLIBC_USING_USER_MEMCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMCPY is not set +# CONFIG_RT_KLIBC_USING_TINY_MEMCPY is not set +# end of rt_memcpy options + +# +# rt_memmove options +# +# CONFIG_RT_KLIBC_USING_USER_MEMMOVE is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMMOVE is not set +# end of rt_memmove options + +# +# rt_memcmp options +# +# CONFIG_RT_KLIBC_USING_USER_MEMCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_MEMCMP is not set +# end of rt_memcmp options + +# +# rt_strstr options +# +# CONFIG_RT_KLIBC_USING_USER_STRSTR is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRSTR is not set +# end of rt_strstr options + +# +# rt_strcasecmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRCASECMP is not set +# end of rt_strcasecmp options + +# +# rt_strncpy options +# +# CONFIG_RT_KLIBC_USING_USER_STRNCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRNCPY is not set +# end of rt_strncpy options + +# +# rt_strcpy options +# +# CONFIG_RT_KLIBC_USING_USER_STRCPY is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRCPY is not set +# end of rt_strcpy options + +# +# rt_strncmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRNCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRNCMP is not set +# end of rt_strncmp options + +# +# rt_strcmp options +# +# CONFIG_RT_KLIBC_USING_USER_STRCMP is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRCMP is not set +# end of rt_strcmp options + +# +# rt_strlen options +# +# CONFIG_RT_KLIBC_USING_USER_STRLEN is not set +# CONFIG_RT_KLIBC_USING_LIBC_STRLEN is not set +# end of rt_strlen options + +# +# rt_strnlen options +# +# CONFIG_RT_KLIBC_USING_USER_STRNLEN is not set +# end of rt_strnlen options +# end of klibc options + +CONFIG_RT_NAME_MAX=16 +# 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_OVERFLOW_CHECK=y +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 is not set +# CONFIG_RT_USING_CPU_USAGE_TRACER is not set + +# +# kservice options +# +# CONFIG_RT_USING_TINY_FFS is not set +# end of kservice options + +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_CI_ACTION is not set + +# +# 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=y +# CONFIG_RT_USING_INTERRUPT_INFO is not set +# CONFIG_RT_USING_THREADSAFE_PRINTF is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=512 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart4" +CONFIG_RT_USING_CONSOLE_OUTPUT_CTL=y +CONFIG_RT_VER_NUM=0x50300 +# 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_WORD_OPERATION is not set +# CONFIG_FINSH_USING_FUNC_EXT is not set +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 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=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +# CONFIG_RT_USING_SERIAL_V1 is not set +CONFIG_RT_USING_SERIAL_V2=y +# CONFIG_RT_SERIAL_BUF_STRATEGY_DROP is not set +CONFIG_RT_SERIAL_BUF_STRATEGY_OVERWRITE=y +# CONFIG_RT_SERIAL_USING_DMA is not set +# CONFIG_RT_USING_SERIAL_BYPASS is not set +CONFIG_RT_USING_CAN=y +# CONFIG_RT_CAN_USING_HDR is not set +# CONFIG_RT_CAN_USING_CANFD is not set +CONFIG_RT_CANMSG_BOX_SZ=16 +CONFIG_RT_CANSND_BOX_NUM=32 +CONFIG_RT_CANSND_MSG_TIMEOUT=100 +CONFIG_RT_CAN_NB_TX_FIFO_SIZE=256 +# CONFIG_RT_CAN_MALLOC_NB_TX_BUFFER is not set +# CONFIG_RT_USING_CLOCK_TIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +# CONFIG_RT_USING_PHY_V2 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_BLK is not set +# CONFIG_RT_USING_REGULATOR is not set +# CONFIG_RT_USING_POWER_SUPPLY is not set +# CONFIG_RT_USING_VIRTIO is not set +CONFIG_RT_USING_PIN=y +# 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 is not set +# 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 + +# +# 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 +# CONFIG_RT_USING_RUST 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 +# CONFIG_PKG_USING_ESP_HOSTED 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 +# CONFIG_PKG_USING_PNET is not set +# CONFIG_PKG_USING_OPENER is not set +# CONFIG_PKG_USING_FREEMQTT 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 +# CONFIG_PKG_USING_RYAN_JSON 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_NES_SIMULATOR is not set +# 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_VECTOR is not set +# CONFIG_PKG_USING_SORCH is not set +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_MCOREDUMP 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 +# CONFIG_PKG_USING_RVBACKTRACE is not set +# CONFIG_PKG_USING_HPATCHLITE is not set +# CONFIG_PKG_USING_THREAD_METRIC is not set +# CONFIG_PKG_USING_UORB is not set +# CONFIG_PKG_USING_RT_TUNNEL is not set +# CONFIG_PKG_USING_VIRTUAL_TERMINAL 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 +# 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_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_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_UART_FRAMEWORK 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_RMP is not set +# CONFIG_PKG_USING_R_RHEALSTONE is not set +# CONFIG_PKG_USING_HEARTBEAT is not set +# CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set +# CONFIG_PKG_USING_CHERRYECAT is not set +# end of system packages + +# +# peripheral libraries and drivers +# + +# +# HAL & SDK Drivers +# + +# +# STM32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_STM32F0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F1_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F1_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F2_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F2_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F3_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F3_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F7_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F7_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32G0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32G0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32G4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32G4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H7_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H7_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H7RS_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H7RS_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32U5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32U5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_STM32WL_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32WL_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32WB_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32WB_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32MP1_M4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32MP1_M4_CMSIS_DRIVER 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_RP2350_SDK is not set +# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_MM32 is not set + +# +# WCH HAL & SDK Drivers +# +# CONFIG_PKG_USING_CH32V20x_SDK is not set +# CONFIG_PKG_USING_CH32V307_SDK is not set +# end of WCH HAL & SDK Drivers + +# +# AT32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_AT32A403A_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32A403A_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32A423_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32A423_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F45x_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F45x_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F402_405_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F402_405_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F403A_407_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F403A_407_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F413_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F413_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F415_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F415_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F421_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F421_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F423_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F423_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F425_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F425_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F435_437_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F435_437_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32M412_416_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32M412_416_CMSIS_DRIVER is not set +# end of AT32 HAL & SDK Drivers + +# +# HC32 DDL Drivers +# +# CONFIG_PKG_USING_HC32F3_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_HC32F3_SERIES_DRIVER is not set +# CONFIG_PKG_USING_HC32F4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_HC32F4_SERIES_DRIVER is not set +# end of HC32 DDL Drivers + +# +# NXP HAL & SDK Drivers +# +# CONFIG_PKG_USING_NXP_MCX_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_NXP_MCX_SERIES_DRIVER is not set +# CONFIG_PKG_USING_NXP_LPC_DRIVER is not set +# CONFIG_PKG_USING_NXP_LPC55S_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMX6SX_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMX6UL_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMXRT_DRIVER is not set +# end of NXP HAL & SDK Drivers + +# +# NUVOTON Drivers +# +# CONFIG_PKG_USING_NUVOTON_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_NUVOTON_SERIES_DRIVER is not set +# CONFIG_PKG_USING_NUVOTON_ARM926_LIB is not set +# end of NUVOTON Drivers + +# +# GD32 Drivers +# +# CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set +# CONFIG_PKG_USING_GD32_RISCV_SERIES_DRIVER is not set +# CONFIG_PKG_USING_GD32VW55X_WIFI is not set +# end of GD32 Drivers + +# +# HPMicro SDK +# +# CONFIG_PKG_USING_HPM_SDK is not set +# end of HPMicro SDK + +# +# FT32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_FT32F0_STD_DRIVER is not set +# CONFIG_PKG_USING_FT32F0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_FT32F4_STD_DRIVER is not set +# CONFIG_PKG_USING_FT32F4_CMSIS_DRIVER is not set +# end of FT32 HAL & SDK Drivers +# 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_MAX31855 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_MLX90382 is not set +# CONFIG_PKG_USING_MLX90384 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90394 is not set +# CONFIG_PKG_USING_MLX90396 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 +# CONFIG_PKG_USING_P3T1755 is not set +# CONFIG_PKG_USING_QMI8658 is not set +# CONFIG_PKG_USING_ICM20948 is not set +# CONFIG_PKG_USING_SCD4X 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_LCD_SPI_DRIVER is not set +# 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_BT_MX02 is not set +# CONFIG_PKG_USING_GC9A01 is not set +# CONFIG_PKG_USING_IK485 is not set +# CONFIG_PKG_USING_SERVO is not set +# CONFIG_PKG_USING_SEAN_WS2812B is not set +# CONFIG_PKG_USING_IC74HC165 is not set +# CONFIG_PKG_USING_IST8310 is not set +# CONFIG_PKG_USING_ST7789_SPI is not set +# CONFIG_PKG_USING_CAN_UDS is not set +# CONFIG_PKG_USING_ISOTP_C is not set +# CONFIG_PKG_USING_IKUNLED is not set +# CONFIG_PKG_USING_INS5T8025 is not set +# CONFIG_PKG_USING_IRUART is not set +# CONFIG_PKG_USING_ST7305 is not set +# CONFIG_PKG_USING_TM1668 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 +# CONFIG_PKG_USING_LLMCHAT 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_LIBCRC 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 +# CONFIG_PKG_USING_DRMP 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_RTDUINO_SENSORFUSION_SHIELD 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 + +# +# Onboard Peripheral Drivers +# +CONFIG_BSP_USING_PINMUX=y +CONFIG_BSP_USING_GPIO=y +CONFIG_BSP_USING_CAN=y +CONFIG_BSP_USING_CAN5=y +CONFIG_BSP_USING_CAN6=y +CONFIG_BSP_USING_CAN7=y +CONFIG_BSP_USING_CAN8=y +CONFIG_BSP_USING_CAN9=y +CONFIG_BSP_USING_UART=y +CONFIG_BSP_USING_UART4=y +CONFIG_BSP_UART4_RX_BUFSIZE=1024 +CONFIG_BSP_UART4_TX_BUFSIZE=0 +# CONFIG_BSP_USING_UART5 is not set +# CONFIG_BSP_USING_UART6 is not set +# end of Onboard Peripheral Drivers diff --git a/bsp/rdk/s100/Kconfig b/bsp/rdk/s100/Kconfig new file mode 100644 index 00000000000..84edaf4b9ec --- /dev/null +++ b/bsp/rdk/s100/Kconfig @@ -0,0 +1,37 @@ +mainmenu "RT-Thread Configuration" + +BSP_DIR := . + +# you can change the RTT_ROOT default "rt-thread" +# example : default "F:/git_repositories/rt-thread" + +PKGS_DIR := packages + +ENV_DIR := / + +config SOC_S100 + bool + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +menu "S100 BSP Options" + +config RT_USING_FPU + bool "Enable Cortex-R52 VFP/FPU support" + default y + help + Enable hardware floating-point support for the S100 BSP. + + When enabled, the BSP builds with hard-float ABI and enables + the VFP context save/restore path. + + When disabled, the BSP switches to a soft-float build so O2 can + remain enabled without generating VFP instructions. + +endmenu + +source "$(RTT_DIR)/Kconfig" +osource "$PKGS_DIR/Kconfig" +# rsource "$(BSP_DIR)/board/Kconfig" +source "$(BSP_DIR)/drivers/Kconfig" diff --git a/bsp/rdk/s100/README.md b/bsp/rdk/s100/README.md new file mode 100644 index 00000000000..e6bd2a1dbd1 --- /dev/null +++ b/bsp/rdk/s100/README.md @@ -0,0 +1,154 @@ +# S100 BSP 编译与加载运行说明 + +本文说明 `bsp/s100` 这个 RT-Thread BSP 如何在主机侧编译,以及如何在 RDK S100 板端加载并运行。 + +说明分两部分: + +- 本地 BSP 实际构建方式:以当前仓库中的 `SConstruct`、`rtconfig.py`、`link.lds` 为准 +- 板端启动流程:参考 D-Robotics 官方文档“[MCU快速入门指南](https://d-robotics.github.io/rdk_doc/rdk_s/Advanced_development/mcu_development/S100/basic_information/)” + +## 1. 背景说明 + +官方文档说明了 S100 的 MCU 启动链路: + +- MCU0 负责启动 Acore、MCU1 和电源管理 +- MCU1 由 Acore 通过 `remoteproc` 框架间接控制 +- 启动时由 Acore 在 `sysfs` 下给 `remoteproc_mcu0` 写入固件名并触发 `start` + +参考: + +- 官方文档第 “MCU1启动/关闭流程” 章节:`remoteproc_mcu0`、`firmware`、`state` +- 本地链接脚本 [link.lds](./link.lds) 也包含 `.resource_table` 段,说明这个镜像是按 remoteproc 风格组织的 MCU1 ELF + +## 2. 主机编译环境 + +### 2.1 推荐系统 + +官方文档建议主机使用 Ubuntu 22.04。 + +### 2.2 依赖安装 + +官方文档给出的依赖如下: + +```bash +sudo apt-get install -y build-essential make cmake libpcre3 libpcre3-dev bc bison \ + flex python3-numpy mtd-utils zlib1g-dev debootstrap \ + libdata-hexdumper-perl libncurses5-dev zip qemu-user-static \ + curl repo git liblz4-tool apt-cacher-ng libssl-dev checkpolicy autoconf \ + android-sdk-libsparse-utils mtools parted dosfstools udev rsync python3-pip scons +pip install "scons>=4.0.0" +pip install ecdsa +pip install tqdm +``` + +### 2.3 交叉工具链 + +当前 BSP 的工具链配置在 [rtconfig.py](./rtconfig.py): + +- 架构:`cortex-r52` +- 工具链前缀:`arm-none-eabi-` +- 默认工具链路径:`/opt/toolchain/gcc-arm-none-eabi-10.3-2021.10/bin` + +如果你的工具链不在这个目录,可以通过环境变量覆盖: + +```bash +export RTT_EXEC_PATH=/your/toolchain/bin +``` + +## 3. BSP 编译方法 + +### 3.1 进入目录 + +```bash +cd /bsp/s100 +``` + +### 3.2 执行编译 + +直接运行: + +```bash +scons -j$(nproc) +``` + +如果你想先清理后重编: + +```bash +scons -c +scons -j$(nproc) +``` + +### 3.3 构建入口 + +本 BSP 的构建入口是: + +- [SConstruct](./SConstruct) +- [rtconfig.py](./rtconfig.py) + +构建特征: + +- 目标文件名:`rtthread.elf` +- 后处理会自动生成:`rtthread.bin` + +## 4. 板端加载运行 + +### 4.1 固件放置 + +根据官方 remoteproc 启动流程,MCU1 固件需要放到板端 `/lib/firmware/`。 + +根据官方 RDK S100 硬件说明,板上有两个有线网口: + +- `U43 / eth0`:通用以太网口,IP 需要通过外部 DHCP 获取,或由用户手动配置静态地址 +- `U45 / eth1`:固定静态 IP 网口,默认地址为 `192.168.127.10` + +如果开发主机直接接在 `U45 / eth1`,可以优先使用固定 IP 方式传文件,这样不需要先查询板端地址。由于当前 BSP 输出文件名是 `rtthread.elf`,可以直接推送这个文件: + +```bash +scp rtthread.elf root@192.168.127.10:/lib/firmware/ +``` + +如果你接的是 `U43 / eth0`,则需要先确认板端实际 IP,然后再执行: + +```bash +scp rtthread.elf root@:/lib/firmware/ +``` + +### 4.2 启动 MCU1 + +参考官方文档中的 `remoteproc_mcu0` 启动步骤,板端执行: + +如果固件名是 `rtthread.elf`: + +```bash +cd /sys/class/remoteproc/remoteproc_mcu0 +echo rtthread.elf > firmware +echo start > state +``` + +### 4.3 停止 MCU1 + +> 由于该功能还不完善,此处需要重启设备来完成 + +## 5. 一套完整示例 + +主机侧: + +```bash +cd /bsp/s100 +scons -j$(nproc) +scp rtthread.elf root@192.168.127.10:/lib/firmware/ +``` + +板端: + +```bash +cd /sys/class/remoteproc/remoteproc_mcu0 +echo rtthread.elf > firmware +echo start > state +``` + +停止: + +```bash +reboot +``` diff --git a/bsp/rdk/s100/SConscript b/bsp/rdk/s100/SConscript new file mode 100644 index 00000000000..6bb37ae2eb5 --- /dev/null +++ b/bsp/rdk/s100/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + group = group + SConscript(os.path.join(d, 'SConscript')) + +Return('group') diff --git a/bsp/rdk/s100/SConstruct b/bsp/rdk/s100/SConstruct new file mode 100644 index 00000000000..2a674084ce5 --- /dev/null +++ b/bsp/rdk/s100/SConstruct @@ -0,0 +1,32 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.join(os.getcwd(), '..', '..', '..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/rdk/s100/applications/SConscript b/bsp/rdk/s100/applications/SConscript new file mode 100644 index 00000000000..3ec48cc8406 --- /dev/null +++ b/bsp/rdk/s100/applications/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rdk/s100/applications/main.c b/bsp/rdk/s100/applications/main.c new file mode 100644 index 00000000000..d7290af2fde --- /dev/null +++ b/bsp/rdk/s100/applications/main.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ +#include + +int main(void) +{ + rt_kprintf("Hi, RT-Thread!\n"); + return 0; +} diff --git a/bsp/rdk/s100/board/SConscript b/bsp/rdk/s100/board/SConscript new file mode 100644 index 00000000000..0de11bedd8b --- /dev/null +++ b/bsp/rdk/s100/board/SConscript @@ -0,0 +1,10 @@ +import os +from building import * + +objs = [] +cwd = GetCurrentDir() +CPPPATH = [cwd] +src = Glob('*.c') + +objs = DefineGroup('board', src, depend = [''], CPPPATH = CPPPATH) +Return('objs') diff --git a/bsp/rdk/s100/board/board.c b/bsp/rdk/s100/board/board.c new file mode 100644 index 00000000000..c88b3de5644 --- /dev/null +++ b/bsp/rdk/s100/board/board.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ + +#include +#include "board.h" + + +void rt_hw_board_init(void) +{ + /* initialize interrupt */ + rt_hw_interrupt_init(); + +#ifdef RT_USING_HEAP + rt_system_heap_init(HEAP_BEGIN, HEAP_END); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif +} diff --git a/bsp/rdk/s100/board/board.h b/bsp/rdk/s100/board/board.h new file mode 100644 index 00000000000..569e697f43c --- /dev/null +++ b/bsp/rdk/s100/board/board.h @@ -0,0 +1,98 @@ +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#ifdef __GNUC__ +extern char OS_HEAP_START_ADDR; +extern char OS_HEAP_END_ADDR; +#define HEAP_BEGIN ((void *)&OS_HEAP_START_ADDR) +#define HEAP_END ((void *)&OS_HEAP_END_ADDR) +#else +#error "GCC support only!" +#endif + +/*********************************************************************************************************************** + * GIC definitions + **********************************************************************************************************************/ +#define S100_GICD_BASE 0x22000000UL +#define S100_GICR0_OFFSET 0x100000UL + +#define GIC_IRQ_START 0 +#define GIC_ACK_INTID_MASK (0x000003FFU) + +/* number of interrupts on board */ +#define ARM_GIC_NR_IRQS (448) +#define MAX_HANDLERS ARM_GIC_NR_IRQS +/* only one GIC available */ +#define ARM_GIC_MAX_NR 1 +/* end defined */ + +#define GICV3_DISTRIBUTOR_BASE_ADDR (S100_GICD_BASE) +#define GICV3_REDISTRIBUTOR_BASE_ADDR (S100_GICD_BASE + S100_GICR0_OFFSET) + +/* + * Board-level IRQ description used by the S100 BSP. + * + * Reason: + * The SoC GIC can see many more interrupt IDs than this RT-Thread board + * actually uses. MCU0 already occupies part of the required interrupt + * resources, so this board only maintains the IRQs used by the current + * port. We keep a board whitelist so GICv3 only configures and controls + * the interrupts that belong to the current board port, which avoids + * touching unrelated SPI lines and reduces the risk of conflicting with + * the interrupts used by MCU0. + * + * Fields: + * irq_number: GIC interrupt ID used by the board. + * enable: whether this IRQ is expected to be enabled by board-level init. + * name: short readable name for debug and dump output. + */ +typedef struct +{ + int irq_number; + rt_bool_t enable; + const char *name; +} s100_rt_irq_config_t; + +/* + * Board-supported external IRQ whitelist. + * + * s100_mcu1_rt_irq_configs records the SPI interrupts currently owned by this + * board port. GICv3 uses this table to decide which external interrupts may be + * initialized, enabled, masked, dumped, or otherwise managed. + * The main purpose is to maintain only the interrupts actually used by this + * side, so we do not accidentally configure or disturb interrupt lines that + * are already required by MCU0. + * + * Private interrupts (SGI/PPI, INTID 0-31) are not listed here because they + * are CPU-local resources and are handled separately. + */ +extern const s100_rt_irq_config_t s100_mcu1_rt_irq_configs[]; +extern const rt_size_t s100_mcu1_rt_irq_configs_count; + +/* Returns RT_TRUE only for IRQs that are managed by the current board port. */ +rt_bool_t s100_board_irq_is_supported(int irq); + +/* the basic constants and interfaces needed by gic */ +rt_inline rt_uint32_t platform_get_gic_dist_base(void) +{ + return GICV3_DISTRIBUTOR_BASE_ADDR; +} + +rt_inline rt_uint32_t platform_get_gic_redist_base(void) +{ + return GICV3_REDISTRIBUTOR_BASE_ADDR; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/rdk/s100/board/rsc_table.c b/bsp/rdk/s100/board/rsc_table.c new file mode 100644 index 00000000000..0a660c0269f --- /dev/null +++ b/bsp/rdk/s100/board/rsc_table.c @@ -0,0 +1,73 @@ + +#include "rsc_table.h" + +extern uint32_t OS_HEAP_START_ADDR; +extern uint32_t OS_HEAP_SIZE; +extern uint32_t MCU_LOG_START_ADDR; +extern uint32_t MCU_LOG_SIZE; +extern uint32_t __SCMI_IPC_START_ADDR; +extern uint32_t __SCMI_IPC_SIZE; +extern uint32_t ATCM_START_ADDR; +extern uint32_t ATCM_SIZE; +extern uint32_t CAN_START_ADDR; +extern uint32_t FLASH_SEC_ADDR; +extern uint32_t FLASH_STARTUP_LEN; + +#define NUM_TABLE_ENTRIES (7) +#define HB_SECTION_T(S) __attribute__((__section__(#S))) +#define HB_RESOURCE HB_SECTION_T(.resource_table) +#define MCU_FLASH_START_BASE_ADDR (0x0CAA5000) +#define MCU_FLASH_BASE_ADDR (0x0CAA5400) +#define MCU_FREERTOS_HEAP_BASE_ADDR ((uint32_t)&OS_HEAP_START_ADDR) +#define MCU_LOG_BASE_ADDR ((uint32_t)&MCU_LOG_START_ADDR) +#define MCU_SCMI_BASE_ADDR ((uint32_t)&__SCMI_IPC_START_ADDR) +#define MCU_ATCM_ADDR ((uint32_t)&ATCM_START_ADDR) +#define MCU_FLASH_START_DDR_ADDR (0x0CAB0000) +#define MCU_FLASH_DDR_ADDR ((uint32_t)&FLASH_SEC_ADDR) +#define MCU_FREERTOS_HEAP_DDR_ADDR ((uint32_t)&OS_HEAP_START_ADDR) +#define MCU_LOG_DDR_ADDR ((uint32_t)&MCU_LOG_START_ADDR) +#define MCU_SCMI_DDR_ADDR ((uint32_t)&__SCMI_IPC_START_ADDR) +#define MCU_BTCM_ADDR ((uint32_t)&CAN_START_ADDR) +#define MCU_FLASH_START_SIZE ((uint32_t)&FLASH_STARTUP_LEN) +#define MCU_FLASH_SIZE (0x2AAC00) +#define MCU_RTTHREAD_HEAP_ADDR ((uint32_t)&OS_HEAP_START_ADDR) +#define MCU_RTTHREAD_HEAP_SIZE ((uint32_t)&OS_HEAP_SIZE) +#define MCU_LOG_SIZE ((uint32_t)&MCU_LOG_SIZE) +#define MCU_SCMI_SIZE ((uint32_t)&__SCMI_IPC_SIZE) +#define MCU_ATCM_SIZE ((uint32_t)&ATCM_SIZE) + +const struct remote_resource_table HB_RESOURCE resources = { + /* Version */ + 1, + + /* NUmber of table entries */ + NUM_TABLE_ENTRIES, + /* reserved fields */ + {0x0, 0x0,}, + + /* Offsets of rsc entries */ + { + // offsetof(struct remote_resource_table, rproc_version), + // offsetof(struct remote_resource_table, fw_chksum), + // offsetof(struct remote_resource_table, ddr_devmem), + // offsetof(struct remote_resource_table, tcm_devmem), + // offsetof(struct remote_resource_table, rpmsg_vdev), + offsetof(struct remote_resource_table, fw_version), + offsetof(struct remote_resource_table, startup_devmem), + offsetof(struct remote_resource_table, flash_devmem), + offsetof(struct remote_resource_table, freertos_heap_devmem), + offsetof(struct remote_resource_table, log_devmem), + offsetof(struct remote_resource_table, scmi_devmem), + offsetof(struct remote_resource_table, atcm_devmem), + }, + + {(uint32_t)RSC_VERSION, {0}, {0}, {0}}, + /* flash_start_mem entry */ + {(uint32_t)RSC_DEVMEM, MCU_FLASH_START_DDR_ADDR, MCU_FLASH_START_DDR_ADDR, MCU_FLASH_START_SIZE, 0, 0, "startup devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_FLASH_DDR_ADDR, MCU_FLASH_DDR_ADDR, MCU_FLASH_SIZE, 0, 0, "flash devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_RTTHREAD_HEAP_ADDR, MCU_RTTHREAD_HEAP_ADDR, MCU_RTTHREAD_HEAP_SIZE, 0, 0, "rtthread_heap devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_LOG_DDR_ADDR, MCU_LOG_DDR_ADDR, MCU_LOG_SIZE, 0, 0, "log devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_SCMI_DDR_ADDR, MCU_SCMI_DDR_ADDR, MCU_SCMI_SIZE, 0, 0, "scmi devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_ATCM_ADDR, MCU_BTCM_ADDR, MCU_ATCM_SIZE, 0, 0, "atcm devmem"}, + +}; diff --git a/bsp/rdk/s100/board/rsc_table.h b/bsp/rdk/s100/board/rsc_table.h new file mode 100644 index 00000000000..a0a447da629 --- /dev/null +++ b/bsp/rdk/s100/board/rsc_table.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * All rights reserved. + * + * Copyright (C) 2015 Xilinx, Inc. All rights reserved. + * Copyright (C) 2023, Horizon Robotics + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Mentor Graphics Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* This file populates resource table for BM remote + * for use by the Linux Master */ +#ifndef HB_RSC_TABLE_H +#define HB_RSC_TABLE_H + +#include +#include + +struct fw_rsc_version_with_type { + uint32_t typefw_rsc_version; + uint8_t version[48]; + uint8_t compile_time[16]; + uint8_t git_hash_id[40]; +}; + +enum fw_resource_type { + RSC_CARVEOUT = 0, + RSC_DEVMEM = 1, + RSC_TRACE = 2, + RSC_VDEV = 3, + RSC_RPROC_MEM = 4U, + RSC_FW_CHKSUM = 5U, + RSC_VERSION = 6U, + RSC_LAST = 7U, + RSC_VENDOR_START = 128, + RSC_VENDOR_END = 512, +}; + +struct fw_rsc_devmem_with_type { + uint32_t typefw_rsc_devmem; + uint32_t da; + uint32_t pa; + uint32_t len; + uint32_t flags; + uint32_t reserved; + uint8_t name[32]; +}; + +#define NO_RESOURCE_ENTRIES (7U) + +/* Resource table for the given remote */ +struct remote_resource_table { + uint32_t version; + uint32_t num; + uint32_t reserved[2]; + uint32_t offset[NO_RESOURCE_ENTRIES]; + struct fw_rsc_version_with_type fw_version; /*PRQA S ALL*/ + struct fw_rsc_devmem_with_type startup_devmem; + struct fw_rsc_devmem_with_type flash_devmem; + struct fw_rsc_devmem_with_type freertos_heap_devmem; + struct fw_rsc_devmem_with_type log_devmem; + struct fw_rsc_devmem_with_type scmi_devmem; + struct fw_rsc_devmem_with_type atcm_devmem; +}__attribute__((packed, aligned(0x100))); + +extern const struct remote_resource_table resources; + +#endif /* RSC_TABLE_H_ */ diff --git a/bsp/rdk/s100/drivers/Kconfig b/bsp/rdk/s100/drivers/Kconfig new file mode 100644 index 00000000000..78a79d015f2 --- /dev/null +++ b/bsp/rdk/s100/drivers/Kconfig @@ -0,0 +1,111 @@ +menu "Onboard Peripheral Drivers" + + config BSP_USING_PINMUX + bool "Enable pinmux helper driver" + default y + help + Enable the S100 pinmux and pin configuration helper APIs. + + config BSP_USING_GPIO + bool "Enable GPIO/pin driver" + default y + select RT_USING_PIN + help + Register the RT-Thread pin device and GPIO interrupt dispatch. + + menuconfig BSP_USING_CAN + bool "Enable CAN (S100 FlexCAN)" + default y + select RT_USING_CAN + help + Enable the S100 FlexCAN driver using RT-Thread CAN framework. + + if BSP_USING_CAN + + config BSP_USING_CAN5 + bool "Enable CAN5" + default y + + config BSP_USING_CAN6 + bool "Enable CAN6" + default y + + config BSP_USING_CAN7 + bool "Enable CAN7" + default y + + config BSP_USING_CAN8 + bool "Enable CAN8" + default y + + config BSP_USING_CAN9 + bool "Enable CAN9" + default y + + endif + + menuconfig BSP_USING_UART + bool "Enable UART" + default y + depends on RT_USING_SERIAL + depends on RT_USING_SERIAL_V2 + + if BSP_USING_UART + + config BSP_USING_UART4 + bool "Enable UART4 (Debugger)" + default y + + if BSP_USING_UART4 + + config BSP_UART4_RX_BUFSIZE + int "Set UART4 RX buffer size" + range 64 65535 + default 1024 + + config BSP_UART4_TX_BUFSIZE + int "Set UART4 TX buffer size" + range 0 65535 + default 0 + + endif + + config BSP_USING_UART5 + bool "Enable UART5" + default n + + if BSP_USING_UART5 + + config BSP_UART5_RX_BUFSIZE + int "Set UART5 RX buffer size" + range 64 65535 + default 1024 + + config BSP_UART5_TX_BUFSIZE + int "Set UART5 TX buffer size" + range 0 65535 + default 0 + + endif + + config BSP_USING_UART6 + bool "Enable UART6" + default n + + if BSP_USING_UART6 + + config BSP_UART6_RX_BUFSIZE + int "Set UART6 RX buffer size" + range 64 65535 + default 1024 + + config BSP_UART6_TX_BUFSIZE + int "Set UART6 TX buffer size" + range 0 65535 + default 0 + + endif + + endif + +endmenu diff --git a/bsp/rdk/s100/drivers/SConscript b/bsp/rdk/s100/drivers/SConscript new file mode 100644 index 00000000000..6b308a4ed17 --- /dev/null +++ b/bsp/rdk/s100/drivers/SConscript @@ -0,0 +1,22 @@ +from building import * + +cwd = GetCurrentDir() +src = [] + +src += ['drv_timer.c'] + +if GetDepend('BSP_USING_UART'): + src += ['drv_uart_v2.c'] + +if GetDepend('BSP_USING_PINMUX'): + src += ['drv_pinmux.c'] + +if GetDepend('BSP_USING_GPIO'): + src += ['drv_gpio.c'] + +if GetDepend('BSP_USING_CAN'): + src += ['drv_can.c'] + +objs = DefineGroup('drivers', src, depend=[''], CPPPATH=[cwd]) + +Return('objs') diff --git a/bsp/rdk/s100/drivers/drv_can.c b/bsp/rdk/s100/drivers/drv_can.c new file mode 100644 index 00000000000..86856edc9c7 --- /dev/null +++ b/bsp/rdk/s100/drivers/drv_can.c @@ -0,0 +1,1313 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ + +#include +#include +#include "interrupt.h" +#include "board.h" +#include "drv_can.h" +#include "drv_gpio.h" + +#define DBG_TAG "drv.can" +#define DBG_LVL DBG_LOG +#include + +#define CAN_RET(_err, _msg) \ + do { LOG_E("%s ret=%d", (_msg), (int)(_err)); return (_err); } while (0) +#define CAN_RET_FMT(_err, _fmt, ...) \ + do { LOG_E(_fmt " ret=%d", ##__VA_ARGS__, (int)(_err)); return (_err); } while (0) + + +#define S100_CAN_CLK_WORKAROUND_BASE (0x2370007CU) +#define S100_CAN_CLK_WORKAROUND_COUNT (10U) +#define S100_CAN_CLK_WORKAROUND_ENABLE (0x8000U) + +#define S100_MCU2CAN_STB_N_PIN (6U) +#define S100_CAN_DEFAULT_CLK_HZ (40000000UL) + +#define S100_CAN5_BASE (0x23720000UL) +#define S100_CAN6_BASE (0x23730000UL) +#define S100_CAN7_BASE (0x23740000UL) +#define S100_CAN8_BASE (0x23750000UL) +#define S100_CAN9_BASE (0x23760000UL) + +#define S100_CAN5_IRQ (136U) +#define S100_CAN6_IRQ (140U) +#define S100_CAN7_IRQ (144U) +#define S100_CAN8_IRQ (148U) +#define S100_CAN9_IRQ (152U) + +#define S100_CAN_MAX_MB_NUM (128U) +#define S100_CAN_MAX_MB_INDEX (55U) +#define S100_CAN_BASIC_TX_MB_START (16U) + +#define S100_CAN_DEFAULT_PRESDIV (1U) +#define S100_CAN_DEFAULT_PROPSEG (7U) +#define S100_CAN_DEFAULT_PSEG1 (8U) +#define S100_CAN_DEFAULT_PSEG2 (4U) +#define S100_CAN_DEFAULT_RJW (2U) + +#define S100_CAN_BASIC_TIMEOUT_LOOP (1000000U) +#define S100_CAN_STD_ID_SHIFT (18U) +#define S100_CAN_STD_ID_MASK (0x7FFU) + +#define S100_CAN_MB_CODE_TX_INACTIVE (0x8U) +#define S100_CAN_MB_CODE_TX_DATA (0xCU) + +#define S100_CAN_ENHANCED_FILTER_STD_SHIFT1 (0U) +#define S100_CAN_ENHANCED_FILTER_STD_SHIFT2 (16U) +#define S100_CAN_ENHANCED_FILTER_FSCH_SHIFT (30U) +#define S100_CAN_ENHANCED_FILTER_STD_MASK (0x7FFU) + +#define S100_CAN_MB_CODE_SHIFT 24U + +struct s100_can_basic_frame +{ + rt_uint32_t cs; + rt_uint32_t id; + rt_uint32_t data0; + rt_uint32_t data1; +}; +typedef struct s100_can_basic_frame s100_can_mb_t; + +struct s100_can_basic_baudrate_cfg +{ + rt_uint32_t presdiv; + rt_uint32_t propseg; + rt_uint32_t pseg1; + rt_uint32_t pseg2; + rt_uint32_t rjw; + rt_bool_t loopback; +}; + +struct s100_can_basic_state +{ + struct rt_ringbuffer rx_rb; + rt_uint8_t rx_rb_pool[S100_CAN_BASIC_TX_MB_START * sizeof(struct s100_can_basic_frame)]; + + rt_uint8_t tx_done; + rt_uint8_t ehfifo_enabled; + rt_uint16_t rx_overrun; +}; + +struct s100_can_basic +{ + const char *name; + s100_can_regs_t *regs; + rt_int32_t irqno; + rt_uint8_t ctrl_id; + rt_uint8_t irq_inited; + rt_uint32_t irq_mask_flags; + struct s100_can_basic_state state; +#ifdef RT_CAN_USING_HDR + rt_uint8_t filter_valid; + struct rt_can_filter_item filter; +#endif + struct rt_can_device can_dev; +}; + +static struct s100_can_basic s100_can_basics[] = +{ +#ifdef BSP_USING_CAN5 + { + .name = "can5", + .regs = (s100_can_regs_t *)S100_CAN5_BASE, + .irqno = S100_CAN5_IRQ, + .ctrl_id = 5U, + }, +#endif +#ifdef BSP_USING_CAN6 + { + .name = "can6", + .regs = (s100_can_regs_t *)S100_CAN6_BASE, + .irqno = S100_CAN6_IRQ, + .ctrl_id = 6U, + }, +#endif +#ifdef BSP_USING_CAN7 + { + .name = "can7", + .regs = (s100_can_regs_t *)S100_CAN7_BASE, + .irqno = S100_CAN7_IRQ, + .ctrl_id = 7U, + }, +#endif +#ifdef BSP_USING_CAN8 + { + .name = "can8", + .regs = (s100_can_regs_t *)S100_CAN8_BASE, + .irqno = S100_CAN8_IRQ, + .ctrl_id = 8U, + }, +#endif +#ifdef BSP_USING_CAN9 + { + .name = "can9", + .regs = (s100_can_regs_t *)S100_CAN9_BASE, + .irqno = S100_CAN9_IRQ, + .ctrl_id = 9U, + }, +#endif +}; + +static inline s100_can_mb_t *s100_can_basic_mb(s100_can_regs_t *base, rt_uint32_t mb_index) +{ + return (s100_can_mb_t *)((rt_uintptr_t)base + + FLEXCAN_IP_FEATURE_RAM_OFFSET + + (mb_index * sizeof(s100_can_mb_t))); +} + +static inline rt_uint32_t s100_can_basic_tx_box_to_mb(rt_uint32_t boxno) +{ + return S100_CAN_BASIC_TX_MB_START + boxno; +} + +static void s100_can_clear_ram_words(volatile rt_uint32_t *ram, rt_uint32_t count) +{ + rt_uint32_t i; + + for (i = 0U; i < count; i++) + { + ram[i] = 0U; + } +} + +static rt_bool_t s100_can_basic_wait_set(volatile rt_uint32_t *reg, rt_uint32_t mask, rt_bool_t set) +{ + rt_uint32_t timeout = S100_CAN_BASIC_TIMEOUT_LOOP; + + while (timeout > 0U) + { + if (set != RT_FALSE) + { + if ((*reg & mask) == mask) + { + return RT_TRUE; + } + } + else + { + if ((*reg & mask) == 0U) + { + return RT_TRUE; + } + } + timeout--; + } + + return RT_FALSE; +} + +static rt_err_t s100_can_basic_enter_freeze(s100_can_regs_t *base) +{ + base->MCR = (base->MCR & ~FLEXCAN_MCR_FRZ_MASK) | FLEXCAN_MCR_FRZ(1U); + base->MCR = (base->MCR & ~FLEXCAN_MCR_HALT_MASK) | FLEXCAN_MCR_HALT(1U); + + if (((base->MCR & FLEXCAN_MCR_MDIS_MASK) >> FLEXCAN_MCR_MDIS_SHIFT) != 0U) + { + base->MCR &= ~FLEXCAN_MCR_MDIS_MASK; + } + + if (s100_can_basic_wait_set(&base->MCR, FLEXCAN_MCR_FRZACK_MASK, RT_TRUE) == RT_FALSE) + { + CAN_RET(-RT_ETIMEOUT, "enter freeze timeout"); + } + + return RT_EOK; +} + +static rt_err_t s100_can_basic_exit_freeze(s100_can_regs_t *base) +{ + base->MCR = (base->MCR & ~FLEXCAN_MCR_HALT_MASK) | FLEXCAN_MCR_HALT(0U); + if (s100_can_basic_wait_set(&base->MCR, FLEXCAN_MCR_FRZACK_MASK, RT_FALSE) == RT_FALSE) + { + CAN_RET(-RT_ETIMEOUT, "exit freeze timeout"); + } + + return RT_EOK; +} + +static rt_err_t s100_can_basic_stop(s100_can_regs_t *base) +{ + if (0U == ((base->MCR & FLEXCAN_MCR_MDIS_MASK) >> FLEXCAN_MCR_MDIS_SHIFT)) + { + base->MCR = (base->MCR & ~FLEXCAN_MCR_MDIS_MASK) | FLEXCAN_MCR_MDIS(1U); + if (s100_can_basic_wait_set(&base->MCR, FLEXCAN_MCR_MDIS_MASK, RT_TRUE) == RT_FALSE) + { + CAN_RET(-RT_ETIMEOUT, "stop controller timeout"); + } + } + + return RT_EOK; +} + +static rt_err_t s100_can_basic_soft_reset(s100_can_regs_t *base) +{ + base->MCR = (base->MCR & ~FLEXCAN_MCR_SOFTRST_MASK) | FLEXCAN_MCR_SOFTRST(1U); + if (s100_can_basic_wait_set(&base->MCR, FLEXCAN_MCR_SOFTRST_MASK, RT_FALSE) == RT_FALSE) + { + CAN_RET(-RT_ETIMEOUT, "soft reset timeout"); + } + + return RT_EOK; +} + +static void s100_can_basic_init_ecc_req_ram(s100_can_regs_t *base) +{ + volatile rt_uint32_t *ram; + + ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_ENHANCED_FIFO_RAM_OFFSET); + s100_can_clear_ram_words(ram, FLEXCAN_IP_FEATURE_ENHANCED_FIFO_RAM_COUNT); + + ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_ENHANCED_FIFO_FILTER_RAM_OFFSET); + s100_can_clear_ram_words(ram, FLEXCAN_ERFFEL_COUNT); + + ram = (volatile rt_uint32_t *)base->RESERVED_4; + s100_can_clear_ram_words(ram, FLEXCAN_IP_FEATURE_SMB_1_RAM_COUNT); + + ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_SMB_2_RAM_OFFSET); + s100_can_clear_ram_words(ram, FLEXCAN_IP_FEATURE_SMB_2_RAM_COUNT); + + ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_RXSMB_TIMESTAMP_RAM_OFFSET); + s100_can_clear_ram_words(ram, FLEXCAN_IP_FEATURE_RXSMB_TIMESTAMP_RAM_COUNT); + + s100_can_clear_ram_words(base->HR_TIME_STAMP, FLEXCAN_HR_TIME_STAMP_COUNT); +} + +static void s100_can_basic_init_flexcan_ram(s100_can_regs_t *base) +{ + volatile rt_uint32_t *ram; + + ram = (volatile rt_uint32_t *)((rt_uintptr_t)base + FLEXCAN_IP_FEATURE_RAM_OFFSET); + s100_can_clear_ram_words(ram, S100_CAN_MAX_MB_NUM * 4U); + s100_can_clear_ram_words(base->RXIMR, S100_CAN_MAX_MB_NUM); + + base->CTRL2 = (base->CTRL2 & ~FLEXCAN_CTRL2_WRMFRZ_MASK) | FLEXCAN_CTRL2_WRMFRZ(1U); + + base->RXMGMASK = 0U; + base->RXFGMASK = 0U; + base->RX14MASK = 0U; + base->RX15MASK = 0U; + + s100_can_basic_init_ecc_req_ram(base); + base->CTRL2 = (base->CTRL2 & ~FLEXCAN_CTRL2_WRMFRZ_MASK) | FLEXCAN_CTRL2_WRMFRZ(0U); +} + +static void s100_can_basic_set_mem_error_detection(s100_can_regs_t *base, rt_uint32_t eccdis) +{ + base->CTRL2 |= FLEXCAN_CTRL2_ECRWRE_MASK; + base->MECR = 0U; + base->MECR |= FLEXCAN_MECR_ECCDIS(eccdis); + base->CTRL2 &= ~FLEXCAN_CTRL2_ECRWRE_MASK; +} + +static rt_uint32_t s100_can_basic_build_mb_cs(rt_uint32_t code, rt_uint32_t dlc, rt_bool_t ide, rt_bool_t rtr) +{ + rt_uint32_t cs = 0U; + + cs |= ((code & 0x0FU) << 24U); + cs |= ((dlc & 0x0FU) << 16U); + if (ide != RT_FALSE) + { + cs |= (1UL << 21) | (1UL << 22); + } + if (rtr != RT_FALSE) + { + cs |= (1UL << 20); + } + + return cs; +} + +static void s100_can_basic_config_ehrxfifo_filters_all_std(struct s100_can_basic *ctrl) +{ + ctrl->regs->ERFFEL[0] = + ((0U & S100_CAN_ENHANCED_FILTER_STD_MASK) << S100_CAN_ENHANCED_FILTER_STD_SHIFT1) | + ((S100_CAN_STD_ID_MASK & S100_CAN_ENHANCED_FILTER_STD_MASK) << S100_CAN_ENHANCED_FILTER_STD_SHIFT2) | + (1U << S100_CAN_ENHANCED_FILTER_FSCH_SHIFT); +} + +static void s100_can_basic_read_ehrxfifo(struct s100_can_basic *ctrl, struct s100_can_basic_frame *frame) +{ + volatile const rt_uint32_t *fifo_ram; + + fifo_ram = (volatile const rt_uint32_t *)((rt_uintptr_t)ctrl->regs + FLEXCAN_IP_FEATURE_ENHANCED_FIFO_RAM_OFFSET); + + frame->cs = fifo_ram[0]; + frame->id = fifo_ram[1]; + frame->data0 = fifo_ram[2]; + frame->data1 = fifo_ram[3]; +} + +static rt_err_t s100_can_basic_init_ehrxfifo(struct s100_can_basic *ctrl, + rt_uint32_t numOfStdIDFilters, + rt_uint32_t numOfExtIDFilters, + rt_uint32_t numOfWatermark) +{ + rt_uint32_t NumOfEnhancedFilters = 0U; + s100_can_regs_t *base = ctrl->regs; + + /* NumOfEnhancedFilters equals (numOfStdIDFilters/2) + numOfExtIDFilters - 1u */ + NumOfEnhancedFilters = (numOfStdIDFilters >> 1u) + numOfExtIDFilters - 1u; + if ((0U == numOfStdIDFilters) && (0U == numOfExtIDFilters)) + { + CAN_RET(-RT_ERROR, "ehrxfifo invalid filter count"); + } + /* If the no of Std Filters is odd */ + if (1U == (numOfStdIDFilters & 1U)) + { + CAN_RET(-RT_ERROR, "ehrxfifo std filter count must be even"); + } + /*Enhanced RX FIFO and Legacy RX FIFO cannot be enabled at the same time.*/ + if (FLEXCAN_MCR_RFEN_MASK == (base->MCR & FLEXCAN_MCR_RFEN_MASK)) + { + CAN_RET(-RT_ERROR, "ehrxfifo conflicts with legacy rxfifo"); + } + + base->ERFIER = 0U; + /* Enable Enhanced Rx FIFO */ + base->ERFCR = (base->ERFCR & ~FLEXCAN_ERFCR_ERFEN_MASK) | FLEXCAN_ERFCR_ERFEN(1U); + /* Reset Enhanced Rx FIFO engine */ + base->ERFSR = (base->ERFSR & ~FLEXCAN_ERFSR_ERFCLR_MASK) | FLEXCAN_ERFSR_ERFCLR(1U); + /* Clear the status bits of the Enhanced RX FIFO */ + base->ERFSR = FLEXCAN_ERFSR_ERFUFW_MASK | + FLEXCAN_ERFSR_ERFOVF_MASK | + FLEXCAN_ERFSR_ERFWMI_MASK | + FLEXCAN_ERFSR_ERFDA_MASK; + /* Set the total number of enhanced Rx FIFO filter elements */ + base->ERFCR = (base->ERFCR & ~FLEXCAN_ERFCR_NFE_MASK) | ((NumOfEnhancedFilters << FLEXCAN_ERFCR_NFE_SHIFT) & FLEXCAN_ERFCR_NFE_MASK); + /* Set the number of extended ID filter elements */ + base->ERFCR = (base->ERFCR & ~FLEXCAN_ERFCR_NEXIF_MASK) | ((numOfExtIDFilters << FLEXCAN_ERFCR_NEXIF_SHIFT) & FLEXCAN_ERFCR_NEXIF_MASK); + /* Set the Enhanced Rx FIFO watermark */ + base->ERFCR = (base->ERFCR & ~FLEXCAN_ERFCR_ERFWM_MASK) | ((numOfWatermark << FLEXCAN_ERFCR_ERFWM_SHIFT) & FLEXCAN_ERFCR_ERFWM_MASK); + s100_can_basic_config_ehrxfifo_filters_all_std(ctrl); + + return RT_EOK; +} + +static void s100_can_basic_init_tx_mb(struct s100_can_basic *ctrl) +{ + rt_uint32_t i; + + for (i = S100_CAN_BASIC_TX_MB_START; i < S100_CAN_MAX_MB_INDEX; i++) + { + s100_can_mb_t *mb = s100_can_basic_mb(ctrl->regs, i); + + mb->cs = 0U; + mb->id = 0U; + mb->data0 = 0U; + mb->data1 = 0U; + mb->cs = s100_can_basic_build_mb_cs(S100_CAN_MB_CODE_TX_INACTIVE, 0U, RT_FALSE, RT_FALSE); + } +} + +static rt_err_t s100_can_basic_wait_ready(s100_can_regs_t *base) +{ + rt_uint32_t timeout = S100_CAN_BASIC_TIMEOUT_LOOP; + + while (timeout > 0U) + { + if (((base->MCR & FLEXCAN_MCR_NOTRDY_MASK) == 0U) && + ((base->ESR1 & FLEXCAN_ESR1_SYNCH_MASK) != 0U)) + { + return RT_EOK; + } + timeout--; + } + + CAN_RET(-RT_ETIMEOUT, "wait ready timeout"); +} + +static void s100_can_basic_update_irq_mask(struct s100_can_basic *ctrl, rt_uint32_t flags, rt_bool_t enable) +{ + rt_uint32_t imask1_tx = 0U; + rt_uint32_t imask2_tx = 0U; + rt_uint32_t i; + + if ((flags & RT_DEVICE_FLAG_INT_TX) != 0U) + { + for (i = S100_CAN_BASIC_TX_MB_START; i < 32U; i++) + { + imask1_tx |= (1UL << i); + } + for (i = 0U; i < (S100_CAN_MAX_MB_INDEX - 32U); i++) + { + imask2_tx |= (1UL << i); + } + + if (enable != RT_FALSE) + { + ctrl->regs->IMASK1 |= imask1_tx; + ctrl->regs->IMASK2 |= imask2_tx; + } + else + { + ctrl->regs->IMASK1 &= ~imask1_tx; + ctrl->regs->IMASK2 &= ~imask2_tx; + } + } + + if ((flags & RT_DEVICE_FLAG_INT_RX) != 0U) + { + if (enable != RT_FALSE) + { + ctrl->regs->ERFIER |= FLEXCAN_ERFIER_ERFDAIE_MASK | + FLEXCAN_ERFIER_ERFOVFIE_MASK | + FLEXCAN_ERFIER_ERFUFWIE_MASK; + } + else + { + ctrl->regs->ERFIER &= ~(FLEXCAN_ERFIER_ERFDAIE_MASK | + FLEXCAN_ERFIER_ERFOVFIE_MASK | + FLEXCAN_ERFIER_ERFUFWIE_MASK); + } + } + + if ((flags & RT_DEVICE_CAN_INT_ERR) != 0U) + { + if (enable != RT_FALSE) + { + ctrl->regs->CTRL1 |= FLEXCAN_CTRL1_ERRMSK_MASK | FLEXCAN_CTRL1_BOFFMSK_MASK; + } + else + { + ctrl->regs->CTRL1 &= ~(FLEXCAN_CTRL1_ERRMSK_MASK | FLEXCAN_CTRL1_BOFFMSK_MASK); + } + } +} + +static rt_err_t s100_can_basic_calc_baudrate_params(struct s100_can_basic *ctrl, + const struct can_configure *cfg, + struct s100_can_basic_baudrate_cfg *baud_cfg) +{ + rt_uint32_t clk_hz; + rt_uint32_t baud; + rt_uint32_t tq_num; + rt_uint32_t presdiv; + + if ((cfg == RT_NULL) || (baud_cfg == RT_NULL)) + { + CAN_RET(-RT_EINVAL, "calc baudrate params invalid argument"); + } + + baud = cfg->baud_rate; + clk_hz = S100_CAN_DEFAULT_CLK_HZ; + + switch (baud) + { + case CAN1MBaud: + case CAN500kBaud: + case CAN250kBaud: + case CAN125kBaud: + case CAN100kBaud: + case CAN50kBaud: + case CAN20kBaud: + case CAN10kBaud: + tq_num = 20U; + baud_cfg->propseg = 7U; + baud_cfg->pseg1 = 8U; + baud_cfg->pseg2 = 4U; + baud_cfg->rjw = 2U; + break; + case CAN800kBaud: + tq_num = 10U; + baud_cfg->propseg = 2U; + baud_cfg->pseg1 = 5U; + baud_cfg->pseg2 = 2U; + baud_cfg->rjw = 2U; + break; + default: + CAN_RET_FMT(-RT_EINVAL, "unsupported nominal baud=%lu", (unsigned long)baud); + } + + if ((baud_cfg->propseg + baud_cfg->pseg1) <= baud_cfg->pseg2) + { + CAN_RET_FMT(-RT_EINVAL, "invalid timing split prop=%lu pseg1=%lu pseg2=%lu", + (unsigned long)baud_cfg->propseg, + (unsigned long)baud_cfg->pseg1, + (unsigned long)baud_cfg->pseg2); + } + + if (baud_cfg->rjw > ((baud_cfg->pseg1 < baud_cfg->pseg2) ? baud_cfg->pseg1 : baud_cfg->pseg2)) + { + CAN_RET_FMT(-RT_EINVAL, "invalid sjw=%lu pseg1=%lu pseg2=%lu", + (unsigned long)baud_cfg->rjw, + (unsigned long)baud_cfg->pseg1, + (unsigned long)baud_cfg->pseg2); + } + + if ((clk_hz % (baud * tq_num)) != 0U) + { + CAN_RET_FMT(-RT_EINVAL, "clock not divisible clk=%lu baud=%lu tq=%lu", + (unsigned long)clk_hz, (unsigned long)baud, (unsigned long)tq_num); + } + + presdiv = clk_hz / (baud * tq_num); + if ((presdiv == 0U) || (presdiv > 1024U)) + { + CAN_RET_FMT(-RT_EINVAL, "invalid presdiv=%lu baud=%lu tq=%lu", + (unsigned long)presdiv, (unsigned long)baud, (unsigned long)tq_num); + } + + baud_cfg->presdiv = presdiv; + return RT_EOK; +} + +static void s100_can_basic_program_baudrate(struct s100_can_basic *ctrl, + const struct s100_can_basic_baudrate_cfg *baud_cfg) +{ + rt_uint32_t ctrl1 = 0U; + rt_uint32_t cbt = 0U; + + ctrl1 |= FLEXCAN_CTRL1_ERRMSK(1U); + ctrl1 |= FLEXCAN_CTRL1_BOFFMSK(1U); + + if (baud_cfg->loopback != RT_FALSE) + { + ctrl1 |= FLEXCAN_CTRL1_LPB(1U); + } + + ctrl->regs->CTRL1 = ctrl1; + + cbt |= FLEXCAN_CBT_BTF(1U); + cbt |= FLEXCAN_CBT_EPRESDIV(baud_cfg->presdiv - 1U); + cbt |= FLEXCAN_CBT_ERJW(baud_cfg->rjw - 1U); + cbt |= FLEXCAN_CBT_EPROPSEG(baud_cfg->propseg - 1U); + cbt |= FLEXCAN_CBT_EPSEG1(baud_cfg->pseg1 - 1U); + cbt |= FLEXCAN_CBT_EPSEG2(baud_cfg->pseg2 - 1U); + ctrl->regs->CBT = cbt; +} + +static void s100_can_basic_apply_baudrate(struct s100_can_basic *ctrl, const struct can_configure *cfg) +{ + struct s100_can_basic_baudrate_cfg baud_cfg; + + baud_cfg.presdiv = S100_CAN_DEFAULT_PRESDIV; + baud_cfg.propseg = S100_CAN_DEFAULT_PROPSEG; + baud_cfg.pseg1 = S100_CAN_DEFAULT_PSEG1; + baud_cfg.pseg2 = S100_CAN_DEFAULT_PSEG2; + baud_cfg.rjw = S100_CAN_DEFAULT_RJW; + baud_cfg.loopback = ((cfg->mode & RT_CAN_MODE_LOOPBACK) != 0U) ? RT_TRUE : RT_FALSE; + + if (s100_can_basic_calc_baudrate_params(ctrl, cfg, &baud_cfg) != RT_EOK) + { + baud_cfg.presdiv = S100_CAN_DEFAULT_PRESDIV; + baud_cfg.propseg = S100_CAN_DEFAULT_PROPSEG; + baud_cfg.pseg1 = S100_CAN_DEFAULT_PSEG1; + baud_cfg.pseg2 = S100_CAN_DEFAULT_PSEG2; + baud_cfg.rjw = S100_CAN_DEFAULT_RJW; + } + + s100_can_basic_program_baudrate(ctrl, &baud_cfg); +} + +static rt_err_t s100_can_basic_apply_baudrate_runtime(struct s100_can_basic *ctrl, rt_uint32_t baud) +{ + struct can_configure cfg; + struct s100_can_basic_baudrate_cfg baud_cfg; + rt_err_t ret; + + cfg = ctrl->can_dev.config; + cfg.baud_rate = baud; + + baud_cfg.presdiv = S100_CAN_DEFAULT_PRESDIV; + baud_cfg.propseg = S100_CAN_DEFAULT_PROPSEG; + baud_cfg.pseg1 = S100_CAN_DEFAULT_PSEG1; + baud_cfg.pseg2 = S100_CAN_DEFAULT_PSEG2; + baud_cfg.rjw = S100_CAN_DEFAULT_RJW; + baud_cfg.loopback = ((cfg.mode & RT_CAN_MODE_LOOPBACK) != 0U) ? RT_TRUE : RT_FALSE; + + ret = s100_can_basic_calc_baudrate_params(ctrl, &cfg, &baud_cfg); + if (ret != RT_EOK) + { + CAN_RET_FMT(ret, "apply baudrate runtime calc params failed baud=%lu", (unsigned long)baud); + } + + ret = s100_can_basic_enter_freeze(ctrl->regs); + if (ret != RT_EOK) + { + CAN_RET(ret, "apply baudrate runtime enter freeze failed"); + } + + s100_can_basic_program_baudrate(ctrl, &baud_cfg); + ret = s100_can_basic_exit_freeze(ctrl->regs); + if (ret != RT_EOK) + { + CAN_RET(ret, "apply baudrate runtime exit freeze failed"); + } + return RT_EOK; +} + +static rt_err_t s100_can_basic_apply_mode(struct s100_can_basic *ctrl, rt_uint32_t mode) +{ + s100_can_regs_t *base = ctrl->regs; + rt_uint32_t mcr; + rt_uint32_t ctrl1; + rt_bool_t loopback; + rt_err_t ret; + + loopback = ((mode & RT_CAN_MODE_LOOPBACK) != 0U) ? RT_TRUE : RT_FALSE; + + ret = s100_can_basic_enter_freeze(base); + if (ret != RT_EOK) + { + CAN_RET(ret, "apply mode enter freeze failed"); + } + + mcr = base->MCR; + mcr &= ~FLEXCAN_MCR_SRXDIS_MASK; + if (loopback == RT_FALSE) + { + mcr |= FLEXCAN_MCR_SRXDIS(1U); + } + base->MCR = mcr; + + ctrl1 = base->CTRL1; + ctrl1 &= ~FLEXCAN_CTRL1_LPB_MASK; + if (loopback != RT_FALSE) + { + ctrl1 |= FLEXCAN_CTRL1_LPB(1U); + } + base->CTRL1 = ctrl1; + + ret = s100_can_basic_exit_freeze(base); + if (ret != RT_EOK) + { + CAN_RET(ret, "apply mode exit freeze failed"); + } + return RT_EOK; +} + +static inline void s100_can_setclksrc(s100_can_regs_t *base, rt_bool_t enable) +{ + base->CTRL1 = (base->CTRL1 & ~FLEXCAN_CTRL1_CLKSRC_MASK) | FLEXCAN_CTRL1_CLKSRC(enable ? 1UL : 0UL); +} + + +static rt_bool_t s100_can_basic_is_enabled(s100_can_regs_t *base) +{ + return (((base->MCR & FLEXCAN_MCR_MDIS_MASK) >> FLEXCAN_MCR_MDIS_SHIFT) != 0U) ? RT_FALSE : RT_TRUE; +} + +static rt_err_t s100_can_basic_init(struct s100_can_basic *ctrl, struct can_configure *cfg) +{ + rt_uint32_t mcr; + rt_err_t ret; + s100_can_regs_t *base = ctrl->regs; + rt_bool_t loopback; + + if (s100_can_basic_is_enabled(base) != RT_FALSE) + { + ret = s100_can_basic_enter_freeze(base); + if (ret != RT_EOK) + { + CAN_RET(ret, "init enter freeze before stop failed"); + } + ret = s100_can_basic_stop(base); + if (ret != RT_EOK) + { + CAN_RET(ret, "init stop failed"); + } + } + + s100_can_setclksrc(base, RT_FALSE); + base->MCR &= ~FLEXCAN_MCR_MDIS_MASK; + ret = s100_can_basic_soft_reset(base); + if (ret != RT_EOK) + { + CAN_RET(ret, "init soft reset failed"); + } + + ret = s100_can_basic_enter_freeze(base); + if (ret != RT_EOK) + { + CAN_RET(ret, "init enter freeze failed"); + } + + mcr = base->MCR; + mcr &= ~(FLEXCAN_MCR_MAXMB_MASK | FLEXCAN_MCR_SRXDIS_MASK); + mcr |= FLEXCAN_MCR_AEN(1U); + mcr |= FLEXCAN_MCR_IRMQ(1U); + mcr |= FLEXCAN_MCR_WRNEN(1U); + mcr |= FLEXCAN_MCR_MAXMB(S100_CAN_MAX_MB_INDEX); + + loopback = ((cfg->mode & RT_CAN_MODE_LOOPBACK) != 0U) ? RT_TRUE : RT_FALSE; + if (loopback == RT_FALSE) + { + mcr |= FLEXCAN_MCR_SRXDIS(1U); + } + base->MCR = mcr; + + s100_can_basic_set_mem_error_detection(base, 0U); + s100_can_basic_init_flexcan_ram(base); + s100_can_basic_apply_baudrate(ctrl, cfg); + + base->IMASK1 = 0U; + base->IMASK2 = 0U; + base->IFLAG1 = 0xFFFFFFFFU; + base->IFLAG2 = 0xFFFFFFFFU; + base->ESR1 = FLEXCAN_IP_ALL_INT; + + s100_can_basic_init_tx_mb(ctrl); + ctrl->state.ehfifo_enabled = 0U; + ret = s100_can_basic_init_ehrxfifo(ctrl, 2U, 0U, 1U); + if (ret != RT_EOK) + { + CAN_RET(ret, "init ehrxfifo failed"); + } + ctrl->state.ehfifo_enabled = 1U; + ctrl->state.tx_done = 0U; + ret = s100_can_basic_exit_freeze(base); + if (ret != RT_EOK) + { + CAN_RET(ret, "init exit freeze failed"); + } + + ret = s100_can_basic_wait_ready(base); + if (ret != RT_EOK) + { + CAN_RET(ret, "init wait ready failed"); + } + return RT_EOK; +} + +static rt_err_t s100_can_basic_send_std(struct s100_can_basic *ctrl, rt_uint32_t std_id, + const rt_uint8_t *data, rt_uint8_t len, rt_uint32_t boxno) +{ + s100_can_mb_t *mb; + rt_uint32_t tx_bit; + rt_uint32_t data0 = 0U; + rt_uint32_t data1 = 0U; + rt_uint32_t code; + rt_uint32_t i; + + if ((data == RT_NULL) || (len > 8U) || (std_id > S100_CAN_STD_ID_MASK)) + { + CAN_RET_FMT(-RT_EINVAL, "send std invalid args id=0x%lx len=%lu", + (unsigned long)std_id, (unsigned long)len); + } + + if (boxno >= ctrl->can_dev.config.sndboxnumber) + { + CAN_RET_FMT(-RT_EINVAL, "send std invalid boxno=%lu sndboxnumber=%lu", + (unsigned long)boxno, (unsigned long)ctrl->can_dev.config.sndboxnumber); + } + + mb = s100_can_basic_mb(ctrl->regs, s100_can_basic_tx_box_to_mb(boxno)); + code = (mb->cs >> S100_CAN_MB_CODE_SHIFT) & 0x0FU; + if (code != S100_CAN_MB_CODE_TX_INACTIVE) + { + CAN_RET_FMT(-RT_EBUSY, "send std mailbox busy boxno=%lu code=0x%lx", + (unsigned long)boxno, (unsigned long)code); + } + + for (i = 0U; i < 4U; i++) + { + data0 <<= 8; + if (i < len) + { + data0 |= data[i]; + } + } + + for (i = 4U; i < 8U; i++) + { + data1 <<= 8; + if (i < len) + { + data1 |= data[i]; + } + } + + ctrl->state.tx_done = 0U; + mb->cs = s100_can_basic_build_mb_cs(S100_CAN_MB_CODE_TX_INACTIVE, 0U, RT_FALSE, RT_FALSE); + mb->id = 0U; + mb->data0 = data0; + mb->data1 = data1; + mb->id = (std_id & S100_CAN_STD_ID_MASK) << S100_CAN_STD_ID_SHIFT; + mb->cs = s100_can_basic_build_mb_cs(S100_CAN_MB_CODE_TX_DATA, len, RT_FALSE, RT_FALSE); + + return RT_EOK; +} + +static void s100_can_basic_handle_tx_irq_bank(struct s100_can_basic *ctrl, + volatile rt_uint32_t *iflag_reg, + rt_uint32_t imask, + rt_uint32_t mb_base) +{ + rt_uint32_t pending; + rt_uint32_t bit; + rt_uint32_t mb_id; + + pending = (*iflag_reg) & imask; + while (pending != 0U) + { + bit = pending & (~pending + 1U); + mb_id = mb_base + (rt_uint32_t)__builtin_ctz(bit); + + (void)ctrl->regs->TIMER; + *iflag_reg = bit; + + if ((mb_id >= S100_CAN_BASIC_TX_MB_START) && + (mb_id < S100_CAN_MAX_MB_INDEX)) + { + ctrl->state.tx_done = 1U; + + if ((ctrl->irq_mask_flags & RT_DEVICE_FLAG_INT_TX) != 0U) + { + rt_hw_can_isr(&ctrl->can_dev, + RT_CAN_EVENT_TX_DONE | ((mb_id - S100_CAN_BASIC_TX_MB_START) << 8)); + } + } + + pending &= ~bit; + } +} + +static void s100_can_basic_handle_ehrxfifo_irq(struct s100_can_basic *ctrl) +{ + rt_uint32_t erf_pending; + struct s100_can_basic_frame frame; + rt_size_t wr_len; + + if ((ctrl == RT_NULL) || (ctrl->state.ehfifo_enabled == 0U)) + { + return; + } + + erf_pending = ctrl->regs->ERFSR & ctrl->regs->ERFIER; + + while ((erf_pending & FLEXCAN_ERFSR_ERFDA_MASK) != 0U) + { + s100_can_basic_read_ehrxfifo(ctrl, &frame); + + wr_len = rt_ringbuffer_put(&ctrl->state.rx_rb, + (const rt_uint8_t *)&frame, + sizeof(frame)); + if (wr_len != sizeof(frame)) + { + ctrl->state.rx_overrun++; + + if ((ctrl->irq_mask_flags & RT_DEVICE_FLAG_INT_RX) != 0U) + { + rt_hw_can_isr(&ctrl->can_dev, RT_CAN_EVENT_RXOF_IND | (1U << 8)); + } + } + else + { + if ((ctrl->irq_mask_flags & RT_DEVICE_FLAG_INT_RX) != 0U) + { + rt_hw_can_isr(&ctrl->can_dev, RT_CAN_EVENT_RX_IND | (1U << 8)); + } + } + + ctrl->regs->ERFSR = FLEXCAN_ERFSR_ERFDA_MASK; + + erf_pending = ctrl->regs->ERFSR & ctrl->regs->ERFIER; + } + + if ((erf_pending & FLEXCAN_ERFSR_ERFOVF_MASK) != 0U) + { + ctrl->regs->ERFSR = FLEXCAN_ERFSR_ERFOVF_MASK; + + if ((ctrl->irq_mask_flags & RT_DEVICE_FLAG_INT_RX) != 0U) + { + rt_hw_can_isr(&ctrl->can_dev, RT_CAN_EVENT_RXOF_IND | (1U << 8)); + } + } + + if ((erf_pending & FLEXCAN_ERFSR_ERFUFW_MASK) != 0U) + { + ctrl->regs->ERFSR = FLEXCAN_ERFSR_ERFUFW_MASK; + } +} + +static void s100_can_basic_irq_handler(int vector, void *param) +{ + struct s100_can_basic *ctrl; + + RT_UNUSED(vector); + ctrl = (struct s100_can_basic *)param; + if (ctrl == RT_NULL) + { + return; + } + + s100_can_basic_handle_tx_irq_bank(ctrl, &ctrl->regs->IFLAG1, ctrl->regs->IMASK1, 0U); + s100_can_basic_handle_tx_irq_bank(ctrl, &ctrl->regs->IFLAG2, ctrl->regs->IMASK2, 32U); + + if (ctrl->state.ehfifo_enabled != 0U) + { + s100_can_basic_handle_ehrxfifo_irq(ctrl); + } + + if ((ctrl->regs->ESR1 & (FLEXCAN_ESR1_ERRINT_MASK | + FLEXCAN_ESR1_BOFFINT_MASK | + FLEXCAN_ESR1_ACKERR_MASK)) != 0U) + { + ctrl->regs->ESR1 = FLEXCAN_IP_ALL_INT; + + if ((ctrl->irq_mask_flags & RT_DEVICE_CAN_INT_ERR) != 0U) + { + rt_hw_can_isr(&ctrl->can_dev, RT_CAN_EVENT_TX_FAIL | (0U << 8)); + } + } +} + +static rt_err_t s100_can_basic_configure(struct rt_can_device *can, struct can_configure *cfg) +{ + struct s100_can_basic *ctrl; + rt_err_t ret; + + RT_ASSERT(can != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + if (cfg->sndboxnumber == 0U) + { + CAN_RET(-RT_EINVAL, "configure invalid sndboxnumber=0"); + } + + //TODO legacy RXFIFO 0-S100_CAN_MAX_MB_INDEX + if (cfg->sndboxnumber > S100_CAN_MAX_MB_INDEX - S100_CAN_BASIC_TX_MB_START) + { + CAN_RET_FMT(-RT_EINVAL, "configure sndboxnumber too large=%lu", + (unsigned long)cfg->sndboxnumber); + } + + if (cfg->msgboxsz == 0U) + { + CAN_RET(-RT_EINVAL, "configure invalid msgboxsz=0"); + } + + ctrl = (struct s100_can_basic *)can->parent.user_data; + if (ctrl == RT_NULL) + { + CAN_RET(-RT_EINVAL, "configure null ctrl"); + } + + rt_ringbuffer_init(&ctrl->state.rx_rb, + ctrl->state.rx_rb_pool, + sizeof(ctrl->state.rx_rb_pool)); + + ctrl->state.rx_overrun = 0U; + + ret = s100_can_basic_init(ctrl,cfg); + if (ret != RT_EOK) + { + CAN_RET_FMT(ret, "configure init failed ctrl=%s", ctrl->name); + } + return RT_EOK; +} + +static rt_err_t s100_can_basic_control(struct rt_can_device *can, int cmd, void *arg) +{ + struct s100_can_basic *ctrl; + + RT_ASSERT(can != RT_NULL); + + ctrl = (struct s100_can_basic *)can->parent.user_data; + if (ctrl == RT_NULL) + { + CAN_RET(-RT_EINVAL, "control null ctrl"); + } + + switch (cmd) + { + case RT_DEVICE_CTRL_SET_INT: + { + rt_uint32_t flags = (rt_uint32_t)(rt_uintptr_t)arg; + + ctrl->irq_mask_flags |= flags; + s100_can_basic_update_irq_mask(ctrl, flags, RT_TRUE); + return RT_EOK; + } + + case RT_DEVICE_CTRL_CLR_INT: + { + rt_uint32_t flags = (rt_uint32_t)(rt_uintptr_t)arg; + + ctrl->irq_mask_flags &= ~flags; + s100_can_basic_update_irq_mask(ctrl, flags, RT_FALSE); + return RT_EOK; + } + + case RT_CAN_CMD_SET_BAUD: + { + rt_uint32_t new_baud = (rt_uint32_t)(rt_uintptr_t)arg; + rt_err_t ret; + + ret = s100_can_basic_apply_baudrate_runtime(ctrl, new_baud); + if (ret == RT_EOK) + { + can->config.baud_rate = new_baud; + } + if (ret != RT_EOK) + { + CAN_RET_FMT(ret, "control set baud failed ctrl=%s baud=%lu", + ctrl->name, (unsigned long)new_baud); + } + return RT_EOK; + } + + case RT_CAN_CMD_SET_MODE: + { + rt_uint32_t new_mode = (rt_uint32_t)(rt_uintptr_t)arg; + rt_err_t ret; + + ret = s100_can_basic_apply_mode(ctrl, new_mode); + if (ret == RT_EOK) + { + can->config.mode = new_mode; + } + if (ret != RT_EOK) + { + CAN_RET_FMT(ret, "control set mode failed ctrl=%s mode=%lu", + ctrl->name, (unsigned long)new_mode); + } + return RT_EOK; + } + + case RT_CAN_CMD_SET_PRIV: + can->config.privmode = (rt_uint32_t)(rt_uintptr_t)arg; + return RT_EOK; + + case RT_CAN_CMD_GET_STATUS: + if (arg == RT_NULL) + { + CAN_RET(-RT_EINVAL, "control get status null arg"); + } + can->status.snderrcnt = ctrl->regs->ECR & 0xFFU; + can->status.rcverrcnt = (ctrl->regs->ECR >> 8U) & 0xFFU; + can->status.errcode = ((ctrl->regs->ESR1 & FLEXCAN_ESR1_BOFFINT_MASK) != 0U) ? BUSOFF : NORMAL; + rt_memcpy(arg, &can->status, sizeof(can->status)); + return RT_EOK; + case RT_CAN_CMD_START: + { + rt_uint32_t next_status = (rt_uint32_t)(rt_uintptr_t)arg; + if(next_status == RT_FALSE) + { + if(s100_can_basic_is_enabled(ctrl->regs)) + { + return s100_can_basic_stop(ctrl->regs); + } + } + return RT_EOK; + } + default: + CAN_RET_FMT(-RT_EINVAL, "control unsupported cmd=%d ctrl=%s", cmd, ctrl->name); + } + return RT_EOK; +} + +static rt_ssize_t s100_can_basic_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno) +{ + struct s100_can_basic *ctrl; + const struct rt_can_msg *msg; + rt_uint32_t retry; + + RT_ASSERT(can != RT_NULL); + + ctrl = (struct s100_can_basic *)can->parent.user_data; + msg = (const struct rt_can_msg *)buf; + if ((ctrl == RT_NULL) || (msg == RT_NULL)) + { + CAN_RET(-RT_EINVAL, "sendmsg null ctrl or msg"); + } + + if (boxno >= ctrl->can_dev.config.sndboxnumber) + { + CAN_RET_FMT(-RT_EINVAL, "sendmsg invalid boxno=%lu sndboxnumber=%lu", + (unsigned long)boxno, (unsigned long)ctrl->can_dev.config.sndboxnumber); + } + + if ((msg->ide != RT_CAN_STDID) || (msg->rtr != RT_CAN_DTR)) + { + CAN_RET_FMT(-RT_ENOSYS, "sendmsg unsupported frame ide=%lu rtr=%lu", + (unsigned long)msg->ide, (unsigned long)msg->rtr); + } + + return s100_can_basic_send_std(ctrl, msg->id, msg->data, (rt_uint8_t)msg->len, boxno); +} + +static rt_ssize_t s100_can_basic_sendmsg_nonblocking(struct rt_can_device *can, const void *buf) +{ + rt_uint32_t boxno; + rt_ssize_t ret; + + for (boxno = 0U; boxno < can->config.sndboxnumber; boxno++) + { + ret = s100_can_basic_sendmsg(can, buf, boxno); + if (ret == RT_EOK) + { + return RT_EOK; + } + if (ret != -RT_EBUSY) + { + CAN_RET_FMT(ret, "sendmsg nonblocking failed boxno=%lu", (unsigned long)boxno); + } + } + + CAN_RET(-RT_EBUSY, "sendmsg nonblocking all mailboxes busy"); +} + +static rt_ssize_t s100_can_basic_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo) +{ + struct s100_can_basic *ctrl; + struct rt_can_msg *msg; + struct s100_can_basic_frame frame; + rt_uint32_t data_word; + rt_uint32_t i; + rt_size_t rd_len; + rt_base_t level; + + RT_ASSERT(can != RT_NULL); + + ctrl = (struct s100_can_basic *)can->parent.user_data; + msg = (struct rt_can_msg *)buf; + + if ((ctrl == RT_NULL) || (msg == RT_NULL) || (fifo == 0U)) + { + CAN_RET_FMT(-RT_EINVAL, "recvmsg invalid args ctrl=%p msg=%p fifo=%lu", + ctrl, msg, (unsigned long)fifo); + } + + level = rt_hw_interrupt_disable(); + rd_len = rt_ringbuffer_get(&ctrl->state.rx_rb, + (rt_uint8_t *)&frame, + sizeof(frame)); + rt_hw_interrupt_enable(level); + + if (rd_len != sizeof(frame)) + { + CAN_RET(-RT_EEMPTY, "recvmsg ringbuffer empty"); + } + + if ((frame.cs & (1UL << 21)) != 0U) + { + CAN_RET(-RT_ENOSYS, "recvmsg ext frame unsupported"); + } + + msg->ide = RT_CAN_STDID; + msg->rtr = ((frame.cs & (1UL << 20)) != 0U) ? RT_CAN_RTR : RT_CAN_DTR; + msg->id = (frame.id >> S100_CAN_STD_ID_SHIFT) & S100_CAN_STD_ID_MASK; + msg->len = (frame.cs >> 16U) & 0x0FU; + if (msg->len > 8U) + { + msg->len = 8U; + } + +#ifdef RT_CAN_USING_HDR + msg->hdr_index = -1; +#else + msg->hdr_index = -1; +#endif + + msg->rxfifo = 0; + msg->priv = 0U; + + data_word = frame.data0; + for (i = 0U; i < 4U; i++) + { + msg->data[i] = (rt_uint8_t)((data_word >> (24U - (i * 8U))) & 0xFFU); + } + + data_word = frame.data1; + for (i = 0U; i < 4U; i++) + { + msg->data[i + 4U] = (rt_uint8_t)((data_word >> (24U - (i * 8U))) & 0xFFU); + } + + return RT_EOK; +} + +static const struct rt_can_ops s100_can_basic_ops = +{ + .configure = s100_can_basic_configure, + .control = s100_can_basic_control, + .sendmsg = s100_can_basic_sendmsg, + .recvmsg = s100_can_basic_recvmsg, + .sendmsg_nonblocking = s100_can_basic_sendmsg_nonblocking, +}; + +static void s100_can_enable_all_clocks_once(void) +{ + volatile rt_uint32_t *reg = (volatile rt_uint32_t *)S100_CAN_CLK_WORKAROUND_BASE; + rt_uint32_t i; + + for (i = 0U; i < S100_CAN_CLK_WORKAROUND_COUNT; i++) + { + reg[i] = S100_CAN_CLK_WORKAROUND_ENABLE; + } + + __DSB(); +} + +void s100_can_board_enable_transceiver(void) +{ + /* Equivalent to Dio_WriteChannel(MCU2CAN_STB_N, STD_LOW). */ + s100_gpio_write(S100_MCU2CAN_STB_N_PIN, 0U); +} + +#define CAN_DEV_SND_BOX_MAX 32U + +int rt_hw_can_init(void) +{ + rt_size_t i; + rt_err_t ret; + struct can_configure cfg = CANDEFAULTCONFIG; + + cfg.privmode = RT_CAN_MODE_NOPRIV; + cfg.ticks = 50U; + + if (cfg.sndboxnumber > CAN_DEV_SND_BOX_MAX) + { + rt_uint32_t requested = cfg.sndboxnumber; + + cfg.sndboxnumber = CAN_DEV_SND_BOX_MAX; + LOG_W("sndboxnumber=%lu exceeds max, capped to %lu", + (unsigned long)requested, + (unsigned long)cfg.sndboxnumber); + } + +#ifdef RT_CAN_USING_HDR + cfg.maxhdr = 1U; +#endif + s100_can_enable_all_clocks_once(); + s100_can_board_enable_transceiver(); + + for (i = 0U; i < (sizeof(s100_can_basics) / sizeof(s100_can_basics[0])); i++) + { + s100_can_basics[i].can_dev.config = cfg; + s100_can_basics[i].can_dev.parent.user_data = &s100_can_basics[i]; + + ret = rt_hw_can_register(&s100_can_basics[i].can_dev, + s100_can_basics[i].name, + &s100_can_basic_ops, + &s100_can_basics[i]); + if (ret != RT_EOK) + { + CAN_RET_FMT(ret, "rt_hw_can_register failed ctrl=%s", s100_can_basics[i].name); + } + + if (s100_can_basics[i].irq_inited == 0U) + { + rt_hw_interrupt_install(s100_can_basics[i].irqno, + s100_can_basic_irq_handler, + &s100_can_basics[i], + s100_can_basics[i].name); + rt_hw_interrupt_set_target_cpus(s100_can_basics[i].irqno, 0U); + rt_hw_interrupt_umask(s100_can_basics[i].irqno); + s100_can_basics[i].irq_inited = 1U; + } + } + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_can_init); diff --git a/bsp/rdk/s100/drivers/drv_can.h b/bsp/rdk/s100/drivers/drv_can.h new file mode 100644 index 00000000000..68febe573db --- /dev/null +++ b/bsp/rdk/s100/drivers/drv_can.h @@ -0,0 +1,1223 @@ +#ifndef DRV_CAN_H__ +#define DRV_CAN_H__ + +#include "rtthread.h" +#include "rtdevice.h" + +#define FLEXCAN_RXIMR_COUNT (32U) +#define FLEXCAN_HR_TIME_STAMP_COUNT (128U) +#define FLEXCAN_ERFFEL_COUNT (128U) + +/*================================================================================================== +* DEFINES AND MACROS +==================================================================================================*/ +/* @brief Frames available in Rx FIFO flag shift */ +#define FLEXCAN_IP_LEGACY_RXFIFO_FRAME_AVAILABLE (5U) +/* @brief Rx FIFO warning flag shift */ +#define FLEXCAN_IP_LEGACY_RXFIFO_WARNING (6U) +/* @brief Rx FIFO overflow flag shift */ +#define FLEXCAN_IP_LEGACY_RXFIFO_OVERFLOW (7U) +/* @brief Frames available in Enhanced Rx FIFO flag shift */ +#define FLEXCAN_IP_ENHANCED_RXFIFO_FRAME_AVAILABLE (28U) +/* @brief Enhanced Rx FIFO Watermark Indication flag shift */ +#define FLEXCAN_IP_ENHANCED_RXFIFO_WATERMARK (29U) +/* @brief Enhanced Rx FIFO Overflow flag shift */ +#define FLEXCAN_IP_ENHANCED_RXFIFO_OVERFLOW (30U) +/* @brief Enhanced Rx FIFO Underflow flag shift */ +#define FLEXCAN_IP_ENHANCED_RXFIFO_UNDERFLOW (31U) +/* @brief FlexCAN Enhanced Fifo Embedded RAM address offset */ +#define FLEXCAN_IP_FEATURE_ENHANCED_FIFO_RAM_OFFSET (0x00002000u) + +/* @brief FlexCAN Enhanced Fifo Embedded RAM count */ +#define FLEXCAN_IP_FEATURE_ENHANCED_FIFO_RAM_COUNT (640u) + +/* @brief FlexCAN Embedded RAM address offset */ +#define FLEXCAN_IP_FEATURE_RAM_OFFSET (0x00000080u) + +/* @brief FlexCAN Expandable Embedded RAM address offset */ +#define FLEXCAN_IP_FEATURE_EXP_RAM_OFFSET (0x00001000u) + +/* @brief FlexCAN Enhanced Fifo filter Embedded RAM address offset */ +#define FLEXCAN_IP_FEATURE_ENHANCED_FIFO_FILTER_RAM_OFFSET (0x00003000U) + +/* @brief FlexCAN Rx SMB Timestamp Embedded RAM address offset */ +#define FLEXCAN_IP_FEATURE_RXSMB_TIMESTAMP_RAM_OFFSET (0xC20U) + +/* @brief FlexCAN Rx SMB Timestamp Embedded RAM count */ +#define FLEXCAN_IP_FEATURE_RXSMB_TIMESTAMP_RAM_COUNT (2U) + +/* @brief FlexCAN SMB 1 Embedded RAM count */ +#define FLEXCAN_IP_FEATURE_SMB_1_RAM_COUNT (120U) + +/* @brief FlexCAN SMB 2 Embedded RAM address offset */ +#define FLEXCAN_IP_FEATURE_SMB_2_RAM_OFFSET (0xF28U) + +/* @brief FlexCAN SMB 2 Embedded RAM count */ +#define FLEXCAN_IP_FEATURE_SMB_2_RAM_COUNT (54U) + +#define FLEXCAN_IP_ALL_INT (0x3B0006U) +#define FLEXCAN_IP_RAM1n_COUNT (512U) + +typedef struct +{ + volatile rt_uint32_t MCR; + volatile rt_uint32_t CTRL1; + volatile rt_uint32_t TIMER; + rt_uint8_t RESERVED_0[4]; + volatile rt_uint32_t RXMGMASK; + volatile rt_uint32_t RX14MASK; + volatile rt_uint32_t RX15MASK; + volatile rt_uint32_t ECR; + volatile rt_uint32_t ESR1; + volatile rt_uint32_t IMASK2; + volatile rt_uint32_t IMASK1; + volatile rt_uint32_t IFLAG2; + volatile rt_uint32_t IFLAG1; + volatile rt_uint32_t CTRL2; + volatile const rt_uint32_t ESR2; + rt_uint8_t RESERVED_1[8]; + volatile const rt_uint32_t CRCR; + volatile rt_uint32_t RXFGMASK; + volatile const rt_uint32_t RXFIR; + volatile rt_uint32_t CBT; + rt_uint8_t RESERVED_2[20]; + volatile rt_uint32_t IMASK4; + volatile rt_uint32_t IMASK3; + volatile rt_uint32_t IFLAG4; + volatile rt_uint32_t IFLAG3; + rt_uint8_t RESERVED_3[2056]; + volatile rt_uint32_t RXIMR[FLEXCAN_RXIMR_COUNT]; + rt_uint8_t RESERVED_4[480]; + volatile rt_uint32_t MECR; + volatile rt_uint32_t ERRIAR; + volatile rt_uint32_t ERRIDPR; + volatile rt_uint32_t ERRIPPR; + volatile const rt_uint32_t RERRAR; + volatile const rt_uint32_t RERRDR; + volatile const rt_uint32_t RERRSYNR; + volatile rt_uint32_t ERRSR; + rt_uint8_t RESERVED_5[240]; + volatile rt_uint32_t EPRS; + volatile rt_uint32_t ENCBT; + volatile rt_uint32_t EDCBT; + volatile rt_uint32_t ETDC; + volatile rt_uint32_t FDCTRL; + volatile rt_uint32_t FDCBT; + volatile const rt_uint32_t FDCRC; + volatile rt_uint32_t ERFCR; + volatile rt_uint32_t ERFIER; + volatile rt_uint32_t ERFSR; + rt_uint8_t RESERVED_6[24]; + volatile rt_uint32_t HR_TIME_STAMP[FLEXCAN_HR_TIME_STAMP_COUNT]; + rt_uint8_t RESERVED_7[8656]; + volatile rt_uint32_t ERFFEL[FLEXCAN_ERFFEL_COUNT]; + volatile rt_uint32_t TSV; + volatile rt_uint32_t TSCTRL; + volatile rt_uint32_t TSLCNT; + volatile rt_uint32_t HREOI; + volatile rt_uint32_t BITEOI; + volatile rt_uint32_t TSIFLAG; +} s100_can_regs_t; + +/* ---------------------------------------------------------------------------- + -- FLEXCAN Register Masks + ---------------------------------------------------------------------------- */ +#define FLEXCAN_MCR_MAXMB_MASK (0x7FU) +#define FLEXCAN_MCR_MAXMB_SHIFT (0U) +#define FLEXCAN_MCR_MAXMB_WIDTH (7U) +#define FLEXCAN_MCR_MAXMB(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_MAXMB_SHIFT)) & FLEXCAN_MCR_MAXMB_MASK) + +#define FLEXCAN_MCR_IDAM_MASK (0x300U) +#define FLEXCAN_MCR_IDAM_SHIFT (8U) +#define FLEXCAN_MCR_IDAM_WIDTH (2U) +#define FLEXCAN_MCR_IDAM(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_IDAM_SHIFT)) & FLEXCAN_MCR_IDAM_MASK) + +#define FLEXCAN_MCR_FDEN_MASK (0x800U) +#define FLEXCAN_MCR_FDEN_SHIFT (11U) +#define FLEXCAN_MCR_FDEN_WIDTH (1U) +#define FLEXCAN_MCR_FDEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_FDEN_SHIFT)) & FLEXCAN_MCR_FDEN_MASK) + +#define FLEXCAN_MCR_AEN_MASK (0x1000U) +#define FLEXCAN_MCR_AEN_SHIFT (12U) +#define FLEXCAN_MCR_AEN_WIDTH (1U) +#define FLEXCAN_MCR_AEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_AEN_SHIFT)) & FLEXCAN_MCR_AEN_MASK) + +#define FLEXCAN_MCR_LPRIOEN_MASK (0x2000U) +#define FLEXCAN_MCR_LPRIOEN_SHIFT (13U) +#define FLEXCAN_MCR_LPRIOEN_WIDTH (1U) +#define FLEXCAN_MCR_LPRIOEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_LPRIOEN_SHIFT)) & FLEXCAN_MCR_LPRIOEN_MASK) + +#define FLEXCAN_MCR_DMA_MASK (0x8000U) +#define FLEXCAN_MCR_DMA_SHIFT (15U) +#define FLEXCAN_MCR_DMA_WIDTH (1U) +#define FLEXCAN_MCR_DMA(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_DMA_SHIFT)) & FLEXCAN_MCR_DMA_MASK) + +#define FLEXCAN_MCR_IRMQ_MASK (0x10000U) +#define FLEXCAN_MCR_IRMQ_SHIFT (16U) +#define FLEXCAN_MCR_IRMQ_WIDTH (1U) +#define FLEXCAN_MCR_IRMQ(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_IRMQ_SHIFT)) & FLEXCAN_MCR_IRMQ_MASK) + +#define FLEXCAN_MCR_SRXDIS_MASK (0x20000U) +#define FLEXCAN_MCR_SRXDIS_SHIFT (17U) +#define FLEXCAN_MCR_SRXDIS_WIDTH (1U) +#define FLEXCAN_MCR_SRXDIS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_SRXDIS_SHIFT)) & FLEXCAN_MCR_SRXDIS_MASK) + +#define FLEXCAN_MCR_LPMACK_MASK (0x100000U) +#define FLEXCAN_MCR_LPMACK_SHIFT (20U) +#define FLEXCAN_MCR_LPMACK_WIDTH (1U) +#define FLEXCAN_MCR_LPMACK(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_LPMACK_SHIFT)) & FLEXCAN_MCR_LPMACK_MASK) + +#define FLEXCAN_MCR_WRNEN_MASK (0x200000U) +#define FLEXCAN_MCR_WRNEN_SHIFT (21U) +#define FLEXCAN_MCR_WRNEN_WIDTH (1U) +#define FLEXCAN_MCR_WRNEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_WRNEN_SHIFT)) & FLEXCAN_MCR_WRNEN_MASK) + +#define FLEXCAN_MCR_FRZACK_MASK (0x1000000U) +#define FLEXCAN_MCR_FRZACK_SHIFT (24U) +#define FLEXCAN_MCR_FRZACK_WIDTH (1U) +#define FLEXCAN_MCR_FRZACK(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_FRZACK_SHIFT)) & FLEXCAN_MCR_FRZACK_MASK) + +#define FLEXCAN_MCR_SOFTRST_MASK (0x2000000U) +#define FLEXCAN_MCR_SOFTRST_SHIFT (25U) +#define FLEXCAN_MCR_SOFTRST_WIDTH (1U) +#define FLEXCAN_MCR_SOFTRST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_SOFTRST_SHIFT)) & FLEXCAN_MCR_SOFTRST_MASK) + +#define FLEXCAN_MCR_NOTRDY_MASK (0x8000000U) +#define FLEXCAN_MCR_NOTRDY_SHIFT (27U) +#define FLEXCAN_MCR_NOTRDY_WIDTH (1U) +#define FLEXCAN_MCR_NOTRDY(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_NOTRDY_SHIFT)) & FLEXCAN_MCR_NOTRDY_MASK) + +#define FLEXCAN_MCR_HALT_MASK (0x10000000U) +#define FLEXCAN_MCR_HALT_SHIFT (28U) +#define FLEXCAN_MCR_HALT_WIDTH (1U) +#define FLEXCAN_MCR_HALT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_HALT_SHIFT)) & FLEXCAN_MCR_HALT_MASK) + +#define FLEXCAN_MCR_RFEN_MASK (0x20000000U) +#define FLEXCAN_MCR_RFEN_SHIFT (29U) +#define FLEXCAN_MCR_RFEN_WIDTH (1U) +#define FLEXCAN_MCR_RFEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_RFEN_SHIFT)) & FLEXCAN_MCR_RFEN_MASK) + +#define FLEXCAN_MCR_FRZ_MASK (0x40000000U) +#define FLEXCAN_MCR_FRZ_SHIFT (30U) +#define FLEXCAN_MCR_FRZ_WIDTH (1U) +#define FLEXCAN_MCR_FRZ(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_FRZ_SHIFT)) & FLEXCAN_MCR_FRZ_MASK) + +#define FLEXCAN_MCR_MDIS_MASK (0x80000000U) +#define FLEXCAN_MCR_MDIS_SHIFT (31U) +#define FLEXCAN_MCR_MDIS_WIDTH (1U) +#define FLEXCAN_MCR_MDIS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MCR_MDIS_SHIFT)) & FLEXCAN_MCR_MDIS_MASK) + +#define FLEXCAN_CTRL1_PROPSEG_MASK (0x7U) +#define FLEXCAN_CTRL1_PROPSEG_SHIFT (0U) +#define FLEXCAN_CTRL1_PROPSEG_WIDTH (3U) +#define FLEXCAN_CTRL1_PROPSEG(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_PROPSEG_SHIFT)) & FLEXCAN_CTRL1_PROPSEG_MASK) + +#define FLEXCAN_CTRL1_LOM_MASK (0x8U) +#define FLEXCAN_CTRL1_LOM_SHIFT (3U) +#define FLEXCAN_CTRL1_LOM_WIDTH (1U) +#define FLEXCAN_CTRL1_LOM(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_LOM_SHIFT)) & FLEXCAN_CTRL1_LOM_MASK) + +#define FLEXCAN_CTRL1_LBUF_MASK (0x10U) +#define FLEXCAN_CTRL1_LBUF_SHIFT (4U) +#define FLEXCAN_CTRL1_LBUF_WIDTH (1U) +#define FLEXCAN_CTRL1_LBUF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_LBUF_SHIFT)) & FLEXCAN_CTRL1_LBUF_MASK) + +#define FLEXCAN_CTRL1_TSYN_MASK (0x20U) +#define FLEXCAN_CTRL1_TSYN_SHIFT (5U) +#define FLEXCAN_CTRL1_TSYN_WIDTH (1U) +#define FLEXCAN_CTRL1_TSYN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_TSYN_SHIFT)) & FLEXCAN_CTRL1_TSYN_MASK) + +#define FLEXCAN_CTRL1_BOFFREC_MASK (0x40U) +#define FLEXCAN_CTRL1_BOFFREC_SHIFT (6U) +#define FLEXCAN_CTRL1_BOFFREC_WIDTH (1U) +#define FLEXCAN_CTRL1_BOFFREC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_BOFFREC_SHIFT)) & FLEXCAN_CTRL1_BOFFREC_MASK) + +#define FLEXCAN_CTRL1_SMP_MASK (0x80U) +#define FLEXCAN_CTRL1_SMP_SHIFT (7U) +#define FLEXCAN_CTRL1_SMP_WIDTH (1U) +#define FLEXCAN_CTRL1_SMP(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_SMP_SHIFT)) & FLEXCAN_CTRL1_SMP_MASK) + +#define FLEXCAN_CTRL1_CLKSRC_MASK (0x2000U)//zjh add +#define FLEXCAN_CTRL1_CLKSRC_SHIFT (13U) +#define FLEXCAN_CTRL1_CLKSRC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_CLKSRC_SHIFT)) & FLEXCAN_CTRL1_CLKSRC_MASK) + + +#define FLEXCAN_CTRL1_RWRNMSK_MASK (0x400U) +#define FLEXCAN_CTRL1_RWRNMSK_SHIFT (10U) +#define FLEXCAN_CTRL1_RWRNMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_RWRNMSK(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_RWRNMSK_SHIFT)) & FLEXCAN_CTRL1_RWRNMSK_MASK) + +#define FLEXCAN_CTRL1_TWRNMSK_MASK (0x800U) +#define FLEXCAN_CTRL1_TWRNMSK_SHIFT (11U) +#define FLEXCAN_CTRL1_TWRNMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_TWRNMSK(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_TWRNMSK_SHIFT)) & FLEXCAN_CTRL1_TWRNMSK_MASK) + +#define FLEXCAN_CTRL1_LPB_MASK (0x1000U) +#define FLEXCAN_CTRL1_LPB_SHIFT (12U) +#define FLEXCAN_CTRL1_LPB_WIDTH (1U) +#define FLEXCAN_CTRL1_LPB(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_LPB_SHIFT)) & FLEXCAN_CTRL1_LPB_MASK) + +#define FLEXCAN_CTRL1_ERRMSK_MASK (0x4000U) +#define FLEXCAN_CTRL1_ERRMSK_SHIFT (14U) +#define FLEXCAN_CTRL1_ERRMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_ERRMSK(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_ERRMSK_SHIFT)) & FLEXCAN_CTRL1_ERRMSK_MASK) + +#define FLEXCAN_CTRL1_BOFFMSK_MASK (0x8000U) +#define FLEXCAN_CTRL1_BOFFMSK_SHIFT (15U) +#define FLEXCAN_CTRL1_BOFFMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_BOFFMSK(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_BOFFMSK_SHIFT)) & FLEXCAN_CTRL1_BOFFMSK_MASK) + +#define FLEXCAN_CTRL1_PSEG2_MASK (0x70000U) +#define FLEXCAN_CTRL1_PSEG2_SHIFT (16U) +#define FLEXCAN_CTRL1_PSEG2_WIDTH (3U) +#define FLEXCAN_CTRL1_PSEG2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_PSEG2_SHIFT)) & FLEXCAN_CTRL1_PSEG2_MASK) + +#define FLEXCAN_CTRL1_PSEG1_MASK (0x380000U) +#define FLEXCAN_CTRL1_PSEG1_SHIFT (19U) +#define FLEXCAN_CTRL1_PSEG1_WIDTH (3U) +#define FLEXCAN_CTRL1_PSEG1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_PSEG1_SHIFT)) & FLEXCAN_CTRL1_PSEG1_MASK) + +#define FLEXCAN_CTRL1_RJW_MASK (0xC00000U) +#define FLEXCAN_CTRL1_RJW_SHIFT (22U) +#define FLEXCAN_CTRL1_RJW_WIDTH (2U) +#define FLEXCAN_CTRL1_RJW(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_RJW_SHIFT)) & FLEXCAN_CTRL1_RJW_MASK) + +#define FLEXCAN_CTRL1_PRESDIV_MASK (0xFF000000U) +#define FLEXCAN_CTRL1_PRESDIV_SHIFT (24U) +#define FLEXCAN_CTRL1_PRESDIV_WIDTH (8U) +#define FLEXCAN_CTRL1_PRESDIV(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_PRESDIV_SHIFT)) & FLEXCAN_CTRL1_PRESDIV_MASK) + +#define FLEXCAN_TIMER_TIMER_MASK (0xFFFFU) +#define FLEXCAN_TIMER_TIMER_SHIFT (0U) +#define FLEXCAN_TIMER_TIMER_WIDTH (16U) +#define FLEXCAN_TIMER_TIMER(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_TIMER_TIMER_SHIFT)) & FLEXCAN_TIMER_TIMER_MASK) + +#define FLEXCAN_RXMGMASK_MG_MASK (0xFFFFFFFFU) +#define FLEXCAN_RXMGMASK_MG_SHIFT (0U) +#define FLEXCAN_RXMGMASK_MG_WIDTH (32U) +#define FLEXCAN_RXMGMASK_MG(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RXMGMASK_MG_SHIFT)) & FLEXCAN_RXMGMASK_MG_MASK) + +#define FLEXCAN_RX14MASK_RX14M_MASK (0xFFFFFFFFU) +#define FLEXCAN_RX14MASK_RX14M_SHIFT (0U) +#define FLEXCAN_RX14MASK_RX14M_WIDTH (32U) +#define FLEXCAN_RX14MASK_RX14M(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RX14MASK_RX14M_SHIFT)) & FLEXCAN_RX14MASK_RX14M_MASK) + +#define FLEXCAN_RX15MASK_RX15M_MASK (0xFFFFFFFFU) +#define FLEXCAN_RX15MASK_RX15M_SHIFT (0U) +#define FLEXCAN_RX15MASK_RX15M_WIDTH (32U) +#define FLEXCAN_RX15MASK_RX15M(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RX15MASK_RX15M_SHIFT)) & FLEXCAN_RX15MASK_RX15M_MASK) + +#define FLEXCAN_ECR_TXERRCNT_MASK (0xFFU) +#define FLEXCAN_ECR_TXERRCNT_SHIFT (0U) +#define FLEXCAN_ECR_TXERRCNT_WIDTH (8U) +#define FLEXCAN_ECR_TXERRCNT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ECR_TXERRCNT_SHIFT)) & FLEXCAN_ECR_TXERRCNT_MASK) + +#define FLEXCAN_ECR_RXERRCNT_MASK (0xFF00U) +#define FLEXCAN_ECR_RXERRCNT_SHIFT (8U) +#define FLEXCAN_ECR_RXERRCNT_WIDTH (8U) +#define FLEXCAN_ECR_RXERRCNT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ECR_RXERRCNT_SHIFT)) & FLEXCAN_ECR_RXERRCNT_MASK) + +#define FLEXCAN_ECR_TXERRCNT_FAST_MASK (0xFF0000U) +#define FLEXCAN_ECR_TXERRCNT_FAST_SHIFT (16U) +#define FLEXCAN_ECR_TXERRCNT_FAST_WIDTH (8U) +#define FLEXCAN_ECR_TXERRCNT_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ECR_TXERRCNT_FAST_SHIFT)) & FLEXCAN_ECR_TXERRCNT_FAST_MASK) + +#define FLEXCAN_ECR_RXERRCNT_FAST_MASK (0xFF000000U) +#define FLEXCAN_ECR_RXERRCNT_FAST_SHIFT (24U) +#define FLEXCAN_ECR_RXERRCNT_FAST_WIDTH (8U) +#define FLEXCAN_ECR_RXERRCNT_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ECR_RXERRCNT_FAST_SHIFT)) & FLEXCAN_ECR_RXERRCNT_FAST_MASK) + +#define FLEXCAN_ESR1_ERRINT_MASK (0x2U) +#define FLEXCAN_ESR1_ERRINT_SHIFT (1U) +#define FLEXCAN_ESR1_ERRINT_WIDTH (1U) +#define FLEXCAN_ESR1_ERRINT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_ERRINT_SHIFT)) & FLEXCAN_ESR1_ERRINT_MASK) + +#define FLEXCAN_ESR1_BOFFINT_MASK (0x4U) +#define FLEXCAN_ESR1_BOFFINT_SHIFT (2U) +#define FLEXCAN_ESR1_BOFFINT_WIDTH (1U) +#define FLEXCAN_ESR1_BOFFINT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_BOFFINT_SHIFT)) & FLEXCAN_ESR1_BOFFINT_MASK) + +#define FLEXCAN_ESR1_RX_MASK (0x8U) +#define FLEXCAN_ESR1_RX_SHIFT (3U) +#define FLEXCAN_ESR1_RX_WIDTH (1U) +#define FLEXCAN_ESR1_RX(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_RX_SHIFT)) & FLEXCAN_ESR1_RX_MASK) + +#define FLEXCAN_ESR1_FLTCONF_MASK (0x30U) +#define FLEXCAN_ESR1_FLTCONF_SHIFT (4U) +#define FLEXCAN_ESR1_FLTCONF_WIDTH (2U) +#define FLEXCAN_ESR1_FLTCONF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_FLTCONF_SHIFT)) & FLEXCAN_ESR1_FLTCONF_MASK) + +#define FLEXCAN_ESR1_TX_MASK (0x40U) +#define FLEXCAN_ESR1_TX_SHIFT (6U) +#define FLEXCAN_ESR1_TX_WIDTH (1U) +#define FLEXCAN_ESR1_TX(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_TX_SHIFT)) & FLEXCAN_ESR1_TX_MASK) + +#define FLEXCAN_ESR1_IDLE_MASK (0x80U) +#define FLEXCAN_ESR1_IDLE_SHIFT (7U) +#define FLEXCAN_ESR1_IDLE_WIDTH (1U) +#define FLEXCAN_ESR1_IDLE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_IDLE_SHIFT)) & FLEXCAN_ESR1_IDLE_MASK) + +#define FLEXCAN_ESR1_RXWRN_MASK (0x100U) +#define FLEXCAN_ESR1_RXWRN_SHIFT (8U) +#define FLEXCAN_ESR1_RXWRN_WIDTH (1U) +#define FLEXCAN_ESR1_RXWRN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_RXWRN_SHIFT)) & FLEXCAN_ESR1_RXWRN_MASK) + +#define FLEXCAN_ESR1_TXWRN_MASK (0x200U) +#define FLEXCAN_ESR1_TXWRN_SHIFT (9U) +#define FLEXCAN_ESR1_TXWRN_WIDTH (1U) +#define FLEXCAN_ESR1_TXWRN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_TXWRN_SHIFT)) & FLEXCAN_ESR1_TXWRN_MASK) + +#define FLEXCAN_ESR1_STFERR_MASK (0x400U) +#define FLEXCAN_ESR1_STFERR_SHIFT (10U) +#define FLEXCAN_ESR1_STFERR_WIDTH (1U) +#define FLEXCAN_ESR1_STFERR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_STFERR_SHIFT)) & FLEXCAN_ESR1_STFERR_MASK) + +#define FLEXCAN_ESR1_FRMERR_MASK (0x800U) +#define FLEXCAN_ESR1_FRMERR_SHIFT (11U) +#define FLEXCAN_ESR1_FRMERR_WIDTH (1U) +#define FLEXCAN_ESR1_FRMERR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_FRMERR_SHIFT)) & FLEXCAN_ESR1_FRMERR_MASK) + +#define FLEXCAN_ESR1_CRCERR_MASK (0x1000U) +#define FLEXCAN_ESR1_CRCERR_SHIFT (12U) +#define FLEXCAN_ESR1_CRCERR_WIDTH (1U) +#define FLEXCAN_ESR1_CRCERR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_CRCERR_SHIFT)) & FLEXCAN_ESR1_CRCERR_MASK) + +#define FLEXCAN_ESR1_ACKERR_MASK (0x2000U) +#define FLEXCAN_ESR1_ACKERR_SHIFT (13U) +#define FLEXCAN_ESR1_ACKERR_WIDTH (1U) +#define FLEXCAN_ESR1_ACKERR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_ACKERR_SHIFT)) & FLEXCAN_ESR1_ACKERR_MASK) + +#define FLEXCAN_ESR1_BIT0ERR_MASK (0x4000U) +#define FLEXCAN_ESR1_BIT0ERR_SHIFT (14U) +#define FLEXCAN_ESR1_BIT0ERR_WIDTH (1U) +#define FLEXCAN_ESR1_BIT0ERR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_BIT0ERR_SHIFT)) & FLEXCAN_ESR1_BIT0ERR_MASK) + +#define FLEXCAN_ESR1_BIT1ERR_MASK (0x8000U) +#define FLEXCAN_ESR1_BIT1ERR_SHIFT (15U) +#define FLEXCAN_ESR1_BIT1ERR_WIDTH (1U) +#define FLEXCAN_ESR1_BIT1ERR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_BIT1ERR_SHIFT)) & FLEXCAN_ESR1_BIT1ERR_MASK) + +#define FLEXCAN_ESR1_RWRNINT_MASK (0x10000U) +#define FLEXCAN_ESR1_RWRNINT_SHIFT (16U) +#define FLEXCAN_ESR1_RWRNINT_WIDTH (1U) +#define FLEXCAN_ESR1_RWRNINT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_RWRNINT_SHIFT)) & FLEXCAN_ESR1_RWRNINT_MASK) + +#define FLEXCAN_ESR1_TWRNINT_MASK (0x20000U) +#define FLEXCAN_ESR1_TWRNINT_SHIFT (17U) +#define FLEXCAN_ESR1_TWRNINT_WIDTH (1U) +#define FLEXCAN_ESR1_TWRNINT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_TWRNINT_SHIFT)) & FLEXCAN_ESR1_TWRNINT_MASK) + +#define FLEXCAN_ESR1_SYNCH_MASK (0x40000U) +#define FLEXCAN_ESR1_SYNCH_SHIFT (18U) +#define FLEXCAN_ESR1_SYNCH_WIDTH (1U) +#define FLEXCAN_ESR1_SYNCH(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_SYNCH_SHIFT)) & FLEXCAN_ESR1_SYNCH_MASK) + +#define FLEXCAN_ESR1_BOFFDONEINT_MASK (0x80000U) +#define FLEXCAN_ESR1_BOFFDONEINT_SHIFT (19U) +#define FLEXCAN_ESR1_BOFFDONEINT_WIDTH (1U) +#define FLEXCAN_ESR1_BOFFDONEINT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_BOFFDONEINT_SHIFT)) & FLEXCAN_ESR1_BOFFDONEINT_MASK) + +#define FLEXCAN_ESR1_ERRINT_FAST_MASK (0x100000U) +#define FLEXCAN_ESR1_ERRINT_FAST_SHIFT (20U) +#define FLEXCAN_ESR1_ERRINT_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_ERRINT_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_ERRINT_FAST_SHIFT)) & FLEXCAN_ESR1_ERRINT_FAST_MASK) + +#define FLEXCAN_ESR1_ERROVR_MASK (0x200000U) +#define FLEXCAN_ESR1_ERROVR_SHIFT (21U) +#define FLEXCAN_ESR1_ERROVR_WIDTH (1U) +#define FLEXCAN_ESR1_ERROVR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_ERROVR_SHIFT)) & FLEXCAN_ESR1_ERROVR_MASK) + +#define FLEXCAN_ESR1_STFERR_FAST_MASK (0x4000000U) +#define FLEXCAN_ESR1_STFERR_FAST_SHIFT (26U) +#define FLEXCAN_ESR1_STFERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_STFERR_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_STFERR_FAST_SHIFT)) & FLEXCAN_ESR1_STFERR_FAST_MASK) + +#define FLEXCAN_ESR1_FRMERR_FAST_MASK (0x8000000U) +#define FLEXCAN_ESR1_FRMERR_FAST_SHIFT (27U) +#define FLEXCAN_ESR1_FRMERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_FRMERR_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_FRMERR_FAST_SHIFT)) & FLEXCAN_ESR1_FRMERR_FAST_MASK) + +#define FLEXCAN_ESR1_CRCERR_FAST_MASK (0x10000000U) +#define FLEXCAN_ESR1_CRCERR_FAST_SHIFT (28U) +#define FLEXCAN_ESR1_CRCERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_CRCERR_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_CRCERR_FAST_SHIFT)) & FLEXCAN_ESR1_CRCERR_FAST_MASK) + +#define FLEXCAN_ESR1_BIT0ERR_FAST_MASK (0x40000000U) +#define FLEXCAN_ESR1_BIT0ERR_FAST_SHIFT (30U) +#define FLEXCAN_ESR1_BIT0ERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_BIT0ERR_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_BIT0ERR_FAST_SHIFT)) & FLEXCAN_ESR1_BIT0ERR_FAST_MASK) + +#define FLEXCAN_ESR1_BIT1ERR_FAST_MASK (0x80000000U) +#define FLEXCAN_ESR1_BIT1ERR_FAST_SHIFT (31U) +#define FLEXCAN_ESR1_BIT1ERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_BIT1ERR_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR1_BIT1ERR_FAST_SHIFT)) & FLEXCAN_ESR1_BIT1ERR_FAST_MASK) + +#define FLEXCAN_IMASK2_BUF63TO32M_MASK (0xFFFFFFFFU) +#define FLEXCAN_IMASK2_BUF63TO32M_SHIFT (0U) +#define FLEXCAN_IMASK2_BUF63TO32M_WIDTH (32U) +#define FLEXCAN_IMASK2_BUF63TO32M(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IMASK2_BUF63TO32M_SHIFT)) & FLEXCAN_IMASK2_BUF63TO32M_MASK) + +#define FLEXCAN_IMASK1_BUF31TO0M_MASK (0xFFFFFFFFU) +#define FLEXCAN_IMASK1_BUF31TO0M_SHIFT (0U) +#define FLEXCAN_IMASK1_BUF31TO0M_WIDTH (32U) +#define FLEXCAN_IMASK1_BUF31TO0M(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IMASK1_BUF31TO0M_SHIFT)) & FLEXCAN_IMASK1_BUF31TO0M_MASK) + +#define FLEXCAN_IFLAG2_BUF63TO32I_MASK (0xFFFFFFFFU) +#define FLEXCAN_IFLAG2_BUF63TO32I_SHIFT (0U) +#define FLEXCAN_IFLAG2_BUF63TO32I_WIDTH (32U) +#define FLEXCAN_IFLAG2_BUF63TO32I(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG2_BUF63TO32I_SHIFT)) & FLEXCAN_IFLAG2_BUF63TO32I_MASK) + +#define FLEXCAN_IFLAG1_BUF0I_MASK (0x1U) +#define FLEXCAN_IFLAG1_BUF0I_SHIFT (0U) +#define FLEXCAN_IFLAG1_BUF0I_WIDTH (1U) +#define FLEXCAN_IFLAG1_BUF0I(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG1_BUF0I_SHIFT)) & FLEXCAN_IFLAG1_BUF0I_MASK) + +#define FLEXCAN_IFLAG1_BUF4TO1I_MASK (0x1EU) +#define FLEXCAN_IFLAG1_BUF4TO1I_SHIFT (1U) +#define FLEXCAN_IFLAG1_BUF4TO1I_WIDTH (4U) +#define FLEXCAN_IFLAG1_BUF4TO1I(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG1_BUF4TO1I_SHIFT)) & FLEXCAN_IFLAG1_BUF4TO1I_MASK) + +#define FLEXCAN_IFLAG1_BUF5I_MASK (0x20U) +#define FLEXCAN_IFLAG1_BUF5I_SHIFT (5U) +#define FLEXCAN_IFLAG1_BUF5I_WIDTH (1U) +#define FLEXCAN_IFLAG1_BUF5I(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG1_BUF5I_SHIFT)) & FLEXCAN_IFLAG1_BUF5I_MASK) + +#define FLEXCAN_IFLAG1_BUF6I_MASK (0x40U) +#define FLEXCAN_IFLAG1_BUF6I_SHIFT (6U) +#define FLEXCAN_IFLAG1_BUF6I_WIDTH (1U) +#define FLEXCAN_IFLAG1_BUF6I(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG1_BUF6I_SHIFT)) & FLEXCAN_IFLAG1_BUF6I_MASK) + +#define FLEXCAN_IFLAG1_BUF7I_MASK (0x80U) +#define FLEXCAN_IFLAG1_BUF7I_SHIFT (7U) +#define FLEXCAN_IFLAG1_BUF7I_WIDTH (1U) +#define FLEXCAN_IFLAG1_BUF7I(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG1_BUF7I_SHIFT)) & FLEXCAN_IFLAG1_BUF7I_MASK) + +#define FLEXCAN_IFLAG1_BUF31TO8I_MASK (0xFFFFFF00U) +#define FLEXCAN_IFLAG1_BUF31TO8I_SHIFT (8U) +#define FLEXCAN_IFLAG1_BUF31TO8I_WIDTH (24U) +#define FLEXCAN_IFLAG1_BUF31TO8I(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG1_BUF31TO8I_SHIFT)) & FLEXCAN_IFLAG1_BUF31TO8I_MASK) + +#define FLEXCAN_CTRL2_TSTAMPCAP_MASK (0xC0U) +#define FLEXCAN_CTRL2_TSTAMPCAP_SHIFT (6U) +#define FLEXCAN_CTRL2_TSTAMPCAP_WIDTH (2U) +#define FLEXCAN_CTRL2_TSTAMPCAP(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_TSTAMPCAP_SHIFT)) & FLEXCAN_CTRL2_TSTAMPCAP_MASK) + +#define FLEXCAN_CTRL2_MBTSBASE_MASK (0x300U) +#define FLEXCAN_CTRL2_MBTSBASE_SHIFT (8U) +#define FLEXCAN_CTRL2_MBTSBASE_WIDTH (2U) +#define FLEXCAN_CTRL2_MBTSBASE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_MBTSBASE_SHIFT)) & FLEXCAN_CTRL2_MBTSBASE_MASK) + +#define FLEXCAN_CTRL2_EDFLTDIS_MASK (0x800U) +#define FLEXCAN_CTRL2_EDFLTDIS_SHIFT (11U) +#define FLEXCAN_CTRL2_EDFLTDIS_WIDTH (1U) +#define FLEXCAN_CTRL2_EDFLTDIS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_EDFLTDIS_SHIFT)) & FLEXCAN_CTRL2_EDFLTDIS_MASK) + +#define FLEXCAN_CTRL2_ISOCANFDEN_MASK (0x1000U) +#define FLEXCAN_CTRL2_ISOCANFDEN_SHIFT (12U) +#define FLEXCAN_CTRL2_ISOCANFDEN_WIDTH (1U) +#define FLEXCAN_CTRL2_ISOCANFDEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_ISOCANFDEN_SHIFT)) & FLEXCAN_CTRL2_ISOCANFDEN_MASK) + +#define FLEXCAN_CTRL2_BTE_MASK (0x2000U) +#define FLEXCAN_CTRL2_BTE_SHIFT (13U) +#define FLEXCAN_CTRL2_BTE_WIDTH (1U) +#define FLEXCAN_CTRL2_BTE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_BTE_SHIFT)) & FLEXCAN_CTRL2_BTE_MASK) + +#define FLEXCAN_CTRL2_PREXCEN_MASK (0x4000U) +#define FLEXCAN_CTRL2_PREXCEN_SHIFT (14U) +#define FLEXCAN_CTRL2_PREXCEN_WIDTH (1U) +#define FLEXCAN_CTRL2_PREXCEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_PREXCEN_SHIFT)) & FLEXCAN_CTRL2_PREXCEN_MASK) + +#define FLEXCAN_CTRL2_TIMER_SRC_MASK (0x8000U) +#define FLEXCAN_CTRL2_TIMER_SRC_SHIFT (15U) +#define FLEXCAN_CTRL2_TIMER_SRC_WIDTH (1U) +#define FLEXCAN_CTRL2_TIMER_SRC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_TIMER_SRC_SHIFT)) & FLEXCAN_CTRL2_TIMER_SRC_MASK) + +#define FLEXCAN_CTRL2_EACEN_MASK (0x10000U) +#define FLEXCAN_CTRL2_EACEN_SHIFT (16U) +#define FLEXCAN_CTRL2_EACEN_WIDTH (1U) +#define FLEXCAN_CTRL2_EACEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_EACEN_SHIFT)) & FLEXCAN_CTRL2_EACEN_MASK) + +#define FLEXCAN_CTRL2_RRS_MASK (0x20000U) +#define FLEXCAN_CTRL2_RRS_SHIFT (17U) +#define FLEXCAN_CTRL2_RRS_WIDTH (1U) +#define FLEXCAN_CTRL2_RRS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_RRS_SHIFT)) & FLEXCAN_CTRL2_RRS_MASK) + +#define FLEXCAN_CTRL2_MRP_MASK (0x40000U) +#define FLEXCAN_CTRL2_MRP_SHIFT (18U) +#define FLEXCAN_CTRL2_MRP_WIDTH (1U) +#define FLEXCAN_CTRL2_MRP(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_MRP_SHIFT)) & FLEXCAN_CTRL2_MRP_MASK) + +#define FLEXCAN_CTRL2_TASD_MASK (0xF80000U) +#define FLEXCAN_CTRL2_TASD_SHIFT (19U) +#define FLEXCAN_CTRL2_TASD_WIDTH (5U) +#define FLEXCAN_CTRL2_TASD(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_TASD_SHIFT)) & FLEXCAN_CTRL2_TASD_MASK) + +#define FLEXCAN_CTRL2_RFFN_MASK (0xF000000U) +#define FLEXCAN_CTRL2_RFFN_SHIFT (24U) +#define FLEXCAN_CTRL2_RFFN_WIDTH (4U) +#define FLEXCAN_CTRL2_RFFN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_RFFN_SHIFT)) & FLEXCAN_CTRL2_RFFN_MASK) + +#define FLEXCAN_CTRL2_WRMFRZ_MASK (0x10000000U) +#define FLEXCAN_CTRL2_WRMFRZ_SHIFT (28U) +#define FLEXCAN_CTRL2_WRMFRZ_WIDTH (1U) +#define FLEXCAN_CTRL2_WRMFRZ(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_WRMFRZ_SHIFT)) & FLEXCAN_CTRL2_WRMFRZ_MASK) + +#define FLEXCAN_CTRL2_ECRWRE_MASK (0x20000000U) +#define FLEXCAN_CTRL2_ECRWRE_SHIFT (29U) +#define FLEXCAN_CTRL2_ECRWRE_WIDTH (1U) +#define FLEXCAN_CTRL2_ECRWRE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_ECRWRE_SHIFT)) & FLEXCAN_CTRL2_ECRWRE_MASK) + +#define FLEXCAN_CTRL2_BOFFDONEMSK_MASK (0x40000000U) +#define FLEXCAN_CTRL2_BOFFDONEMSK_SHIFT (30U) +#define FLEXCAN_CTRL2_BOFFDONEMSK_WIDTH (1U) +#define FLEXCAN_CTRL2_BOFFDONEMSK(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_BOFFDONEMSK_SHIFT)) & FLEXCAN_CTRL2_BOFFDONEMSK_MASK) + +#define FLEXCAN_CTRL2_ERRMSK_FAST_MASK (0x80000000U) +#define FLEXCAN_CTRL2_ERRMSK_FAST_SHIFT (31U) +#define FLEXCAN_CTRL2_ERRMSK_FAST_WIDTH (1U) +#define FLEXCAN_CTRL2_ERRMSK_FAST(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL2_ERRMSK_FAST_SHIFT)) & FLEXCAN_CTRL2_ERRMSK_FAST_MASK) + +#define FLEXCAN_ESR2_IMB_MASK (0x2000U) +#define FLEXCAN_ESR2_IMB_SHIFT (13U) +#define FLEXCAN_ESR2_IMB_WIDTH (1U) +#define FLEXCAN_ESR2_IMB(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR2_IMB_SHIFT)) & FLEXCAN_ESR2_IMB_MASK) + +#define FLEXCAN_ESR2_VPS_MASK (0x4000U) +#define FLEXCAN_ESR2_VPS_SHIFT (14U) +#define FLEXCAN_ESR2_VPS_WIDTH (1U) +#define FLEXCAN_ESR2_VPS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR2_VPS_SHIFT)) & FLEXCAN_ESR2_VPS_MASK) + +#define FLEXCAN_ESR2_LPTM_MASK (0x7F0000U) +#define FLEXCAN_ESR2_LPTM_SHIFT (16U) +#define FLEXCAN_ESR2_LPTM_WIDTH (7U) +#define FLEXCAN_ESR2_LPTM(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ESR2_LPTM_SHIFT)) & FLEXCAN_ESR2_LPTM_MASK) + +#define FLEXCAN_CRCR_TXCRC_MASK (0x7FFFU) +#define FLEXCAN_CRCR_TXCRC_SHIFT (0U) +#define FLEXCAN_CRCR_TXCRC_WIDTH (15U) +#define FLEXCAN_CRCR_TXCRC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CRCR_TXCRC_SHIFT)) & FLEXCAN_CRCR_TXCRC_MASK) + +#define FLEXCAN_CRCR_MBCRC_MASK (0x7F0000U) +#define FLEXCAN_CRCR_MBCRC_SHIFT (16U) +#define FLEXCAN_CRCR_MBCRC_WIDTH (7U) +#define FLEXCAN_CRCR_MBCRC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CRCR_MBCRC_SHIFT)) & FLEXCAN_CRCR_MBCRC_MASK) + +#define FLEXCAN_RXFGMASK_FGM_MASK (0xFFFFFFFFU) +#define FLEXCAN_RXFGMASK_FGM_SHIFT (0U) +#define FLEXCAN_RXFGMASK_FGM_WIDTH (32U) +#define FLEXCAN_RXFGMASK_FGM(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RXFGMASK_FGM_SHIFT)) & FLEXCAN_RXFGMASK_FGM_MASK) + +#define FLEXCAN_RXFIR_IDHIT_MASK (0x1FFU) +#define FLEXCAN_RXFIR_IDHIT_SHIFT (0U) +#define FLEXCAN_RXFIR_IDHIT_WIDTH (9U) +#define FLEXCAN_RXFIR_IDHIT(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RXFIR_IDHIT_SHIFT)) & FLEXCAN_RXFIR_IDHIT_MASK) + +#define FLEXCAN_CBT_EPSEG2_MASK (0x1FU) +#define FLEXCAN_CBT_EPSEG2_SHIFT (0U) +#define FLEXCAN_CBT_EPSEG2_WIDTH (5U) +#define FLEXCAN_CBT_EPSEG2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CBT_EPSEG2_SHIFT)) & FLEXCAN_CBT_EPSEG2_MASK) + +#define FLEXCAN_CBT_EPSEG1_MASK (0x3E0U) +#define FLEXCAN_CBT_EPSEG1_SHIFT (5U) +#define FLEXCAN_CBT_EPSEG1_WIDTH (5U) +#define FLEXCAN_CBT_EPSEG1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CBT_EPSEG1_SHIFT)) & FLEXCAN_CBT_EPSEG1_MASK) + +#define FLEXCAN_CBT_EPROPSEG_MASK (0xFC00U) +#define FLEXCAN_CBT_EPROPSEG_SHIFT (10U) +#define FLEXCAN_CBT_EPROPSEG_WIDTH (6U) +#define FLEXCAN_CBT_EPROPSEG(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CBT_EPROPSEG_SHIFT)) & FLEXCAN_CBT_EPROPSEG_MASK) + +#define FLEXCAN_CBT_ERJW_MASK (0x1F0000U) +#define FLEXCAN_CBT_ERJW_SHIFT (16U) +#define FLEXCAN_CBT_ERJW_WIDTH (5U) +#define FLEXCAN_CBT_ERJW(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CBT_ERJW_SHIFT)) & FLEXCAN_CBT_ERJW_MASK) + +#define FLEXCAN_CBT_EPRESDIV_MASK (0x7FE00000U) +#define FLEXCAN_CBT_EPRESDIV_SHIFT (21U) +#define FLEXCAN_CBT_EPRESDIV_WIDTH (10U) +#define FLEXCAN_CBT_EPRESDIV(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CBT_EPRESDIV_SHIFT)) & FLEXCAN_CBT_EPRESDIV_MASK) + +#define FLEXCAN_CBT_BTF_MASK (0x80000000U) +#define FLEXCAN_CBT_BTF_SHIFT (31U) +#define FLEXCAN_CBT_BTF_WIDTH (1U) +#define FLEXCAN_CBT_BTF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CBT_BTF_SHIFT)) & FLEXCAN_CBT_BTF_MASK) + +#define FLEXCAN_IMASK4_BUF127TO96M_MASK (0xFFFFFFFFU) +#define FLEXCAN_IMASK4_BUF127TO96M_SHIFT (0U) +#define FLEXCAN_IMASK4_BUF127TO96M_WIDTH (32U) +#define FLEXCAN_IMASK4_BUF127TO96M(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IMASK4_BUF127TO96M_SHIFT)) & FLEXCAN_IMASK4_BUF127TO96M_MASK) + +#define FLEXCAN_IMASK3_BUF95TO64M_MASK (0xFFFFFFFFU) +#define FLEXCAN_IMASK3_BUF95TO64M_SHIFT (0U) +#define FLEXCAN_IMASK3_BUF95TO64M_WIDTH (32U) +#define FLEXCAN_IMASK3_BUF95TO64M(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IMASK3_BUF95TO64M_SHIFT)) & FLEXCAN_IMASK3_BUF95TO64M_MASK) + +#define FLEXCAN_IFLAG4_BUF127TO96_MASK (0xFFFFFFFFU) +#define FLEXCAN_IFLAG4_BUF127TO96_SHIFT (0U) +#define FLEXCAN_IFLAG4_BUF127TO96_WIDTH (32U) +#define FLEXCAN_IFLAG4_BUF127TO96(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG4_BUF127TO96_SHIFT)) & FLEXCAN_IFLAG4_BUF127TO96_MASK) + +#define FLEXCAN_IFLAG3_BUF95TO64_MASK (0xFFFFFFFFU) +#define FLEXCAN_IFLAG3_BUF95TO64_SHIFT (0U) +#define FLEXCAN_IFLAG3_BUF95TO64_WIDTH (32U) +#define FLEXCAN_IFLAG3_BUF95TO64(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_IFLAG3_BUF95TO64_SHIFT)) & FLEXCAN_IFLAG3_BUF95TO64_MASK) + +#define FLEXCAN_RXIMR_MI_MASK (0xFFFFFFFFU) +#define FLEXCAN_RXIMR_MI_SHIFT (0U) +#define FLEXCAN_RXIMR_MI_WIDTH (32U) +#define FLEXCAN_RXIMR_MI(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RXIMR_MI_SHIFT)) & FLEXCAN_RXIMR_MI_MASK) + +#define FLEXCAN_MECR_NCEFAFRZ_MASK (0x80U) +#define FLEXCAN_MECR_NCEFAFRZ_SHIFT (7U) +#define FLEXCAN_MECR_NCEFAFRZ_WIDTH (1U) +#define FLEXCAN_MECR_NCEFAFRZ(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_NCEFAFRZ_SHIFT)) & FLEXCAN_MECR_NCEFAFRZ_MASK) + +#define FLEXCAN_MECR_ECCDIS_MASK (0x100U) +#define FLEXCAN_MECR_ECCDIS_SHIFT (8U) +#define FLEXCAN_MECR_ECCDIS_WIDTH (1U) +#define FLEXCAN_MECR_ECCDIS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_ECCDIS_SHIFT)) & FLEXCAN_MECR_ECCDIS_MASK) + +#define FLEXCAN_MECR_RERRDIS_MASK (0x200U) +#define FLEXCAN_MECR_RERRDIS_SHIFT (9U) +#define FLEXCAN_MECR_RERRDIS_WIDTH (1U) +#define FLEXCAN_MECR_RERRDIS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_RERRDIS_SHIFT)) & FLEXCAN_MECR_RERRDIS_MASK) + +#define FLEXCAN_MECR_EXTERRIE_MASK (0x2000U) +#define FLEXCAN_MECR_EXTERRIE_SHIFT (13U) +#define FLEXCAN_MECR_EXTERRIE_WIDTH (1U) +#define FLEXCAN_MECR_EXTERRIE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_EXTERRIE_SHIFT)) & FLEXCAN_MECR_EXTERRIE_MASK) + +#define FLEXCAN_MECR_FAERRIE_MASK (0x4000U) +#define FLEXCAN_MECR_FAERRIE_SHIFT (14U) +#define FLEXCAN_MECR_FAERRIE_WIDTH (1U) +#define FLEXCAN_MECR_FAERRIE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_FAERRIE_SHIFT)) & FLEXCAN_MECR_FAERRIE_MASK) + +#define FLEXCAN_MECR_HAERRIE_MASK (0x8000U) +#define FLEXCAN_MECR_HAERRIE_SHIFT (15U) +#define FLEXCAN_MECR_HAERRIE_WIDTH (1U) +#define FLEXCAN_MECR_HAERRIE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_HAERRIE_SHIFT)) & FLEXCAN_MECR_HAERRIE_MASK) + +#define FLEXCAN_MECR_CEI_MASK (0x10000U) +#define FLEXCAN_MECR_CEI_SHIFT (16U) +#define FLEXCAN_MECR_CEI_WIDTH (1U) +#define FLEXCAN_MECR_CEI(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_CEI_SHIFT)) & FLEXCAN_MECR_CEI_MASK) + +#define FLEXCAN_MECR_FANCEI_MASK (0x40000U) +#define FLEXCAN_MECR_FANCEI_SHIFT (18U) +#define FLEXCAN_MECR_FANCEI_WIDTH (1U) +#define FLEXCAN_MECR_FANCEI(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_FANCEI_SHIFT)) & FLEXCAN_MECR_FANCEI_MASK) + +#define FLEXCAN_MECR_HANCEI_MASK (0x80000U) +#define FLEXCAN_MECR_HANCEI_SHIFT (19U) +#define FLEXCAN_MECR_HANCEI_WIDTH (1U) +#define FLEXCAN_MECR_HANCEI(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_HANCEI_SHIFT)) & FLEXCAN_MECR_HANCEI_MASK) + +#define FLEXCAN_MECR_ECRWRDIS_MASK (0x80000000U) +#define FLEXCAN_MECR_ECRWRDIS_SHIFT (31U) +#define FLEXCAN_MECR_ECRWRDIS_WIDTH (1U) +#define FLEXCAN_MECR_ECRWRDIS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_MECR_ECRWRDIS_SHIFT)) & FLEXCAN_MECR_ECRWRDIS_MASK) + +#define FLEXCAN_ERRIAR_INJADDR_L_MASK (0x3U) +#define FLEXCAN_ERRIAR_INJADDR_L_SHIFT (0U) +#define FLEXCAN_ERRIAR_INJADDR_L_WIDTH (2U) +#define FLEXCAN_ERRIAR_INJADDR_L(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRIAR_INJADDR_L_SHIFT)) & FLEXCAN_ERRIAR_INJADDR_L_MASK) + +#define FLEXCAN_ERRIAR_INJADDR_H_MASK (0x3FFCU) +#define FLEXCAN_ERRIAR_INJADDR_H_SHIFT (2U) +#define FLEXCAN_ERRIAR_INJADDR_H_WIDTH (12U) +#define FLEXCAN_ERRIAR_INJADDR_H(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRIAR_INJADDR_H_SHIFT)) & FLEXCAN_ERRIAR_INJADDR_H_MASK) + +#define FLEXCAN_ERRIDPR_DFLIP_MASK (0xFFFFFFFFU) +#define FLEXCAN_ERRIDPR_DFLIP_SHIFT (0U) +#define FLEXCAN_ERRIDPR_DFLIP_WIDTH (32U) +#define FLEXCAN_ERRIDPR_DFLIP(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRIDPR_DFLIP_SHIFT)) & FLEXCAN_ERRIDPR_DFLIP_MASK) + +#define FLEXCAN_ERRIPPR_PFLIP0_MASK (0x1FU) +#define FLEXCAN_ERRIPPR_PFLIP0_SHIFT (0U) +#define FLEXCAN_ERRIPPR_PFLIP0_WIDTH (5U) +#define FLEXCAN_ERRIPPR_PFLIP0(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRIPPR_PFLIP0_SHIFT)) & FLEXCAN_ERRIPPR_PFLIP0_MASK) + +#define FLEXCAN_ERRIPPR_PFLIP1_MASK (0x1F00U) +#define FLEXCAN_ERRIPPR_PFLIP1_SHIFT (8U) +#define FLEXCAN_ERRIPPR_PFLIP1_WIDTH (5U) +#define FLEXCAN_ERRIPPR_PFLIP1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRIPPR_PFLIP1_SHIFT)) & FLEXCAN_ERRIPPR_PFLIP1_MASK) + +#define FLEXCAN_ERRIPPR_PFLIP2_MASK (0x1F0000U) +#define FLEXCAN_ERRIPPR_PFLIP2_SHIFT (16U) +#define FLEXCAN_ERRIPPR_PFLIP2_WIDTH (5U) +#define FLEXCAN_ERRIPPR_PFLIP2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRIPPR_PFLIP2_SHIFT)) & FLEXCAN_ERRIPPR_PFLIP2_MASK) + +#define FLEXCAN_ERRIPPR_PFLIP3_MASK (0x1F000000U) +#define FLEXCAN_ERRIPPR_PFLIP3_SHIFT (24U) +#define FLEXCAN_ERRIPPR_PFLIP3_WIDTH (5U) +#define FLEXCAN_ERRIPPR_PFLIP3(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRIPPR_PFLIP3_SHIFT)) & FLEXCAN_ERRIPPR_PFLIP3_MASK) + +#define FLEXCAN_RERRAR_ERRADDR_MASK (0x3FFFU) +#define FLEXCAN_RERRAR_ERRADDR_SHIFT (0U) +#define FLEXCAN_RERRAR_ERRADDR_WIDTH (14U) +#define FLEXCAN_RERRAR_ERRADDR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRAR_ERRADDR_SHIFT)) & FLEXCAN_RERRAR_ERRADDR_MASK) + +#define FLEXCAN_RERRAR_SAID_MASK (0x70000U) +#define FLEXCAN_RERRAR_SAID_SHIFT (16U) +#define FLEXCAN_RERRAR_SAID_WIDTH (3U) +#define FLEXCAN_RERRAR_SAID(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRAR_SAID_SHIFT)) & FLEXCAN_RERRAR_SAID_MASK) + +#define FLEXCAN_RERRAR_NCE_MASK (0x1000000U) +#define FLEXCAN_RERRAR_NCE_SHIFT (24U) +#define FLEXCAN_RERRAR_NCE_WIDTH (1U) +#define FLEXCAN_RERRAR_NCE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRAR_NCE_SHIFT)) & FLEXCAN_RERRAR_NCE_MASK) + +#define FLEXCAN_RERRDR_RDATA_MASK (0xFFFFFFFFU) +#define FLEXCAN_RERRDR_RDATA_SHIFT (0U) +#define FLEXCAN_RERRDR_RDATA_WIDTH (32U) +#define FLEXCAN_RERRDR_RDATA(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRDR_RDATA_SHIFT)) & FLEXCAN_RERRDR_RDATA_MASK) + +#define FLEXCAN_RERRSYNR_SYND0_MASK (0x1FU) +#define FLEXCAN_RERRSYNR_SYND0_SHIFT (0U) +#define FLEXCAN_RERRSYNR_SYND0_WIDTH (5U) +#define FLEXCAN_RERRSYNR_SYND0(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRSYNR_SYND0_SHIFT)) & FLEXCAN_RERRSYNR_SYND0_MASK) + +#define FLEXCAN_RERRSYNR_BE0_MASK (0x80U) +#define FLEXCAN_RERRSYNR_BE0_SHIFT (7U) +#define FLEXCAN_RERRSYNR_BE0_WIDTH (1U) +#define FLEXCAN_RERRSYNR_BE0(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRSYNR_BE0_SHIFT)) & FLEXCAN_RERRSYNR_BE0_MASK) + +#define FLEXCAN_RERRSYNR_SYND1_MASK (0x1F00U) +#define FLEXCAN_RERRSYNR_SYND1_SHIFT (8U) +#define FLEXCAN_RERRSYNR_SYND1_WIDTH (5U) +#define FLEXCAN_RERRSYNR_SYND1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRSYNR_SYND1_SHIFT)) & FLEXCAN_RERRSYNR_SYND1_MASK) + +#define FLEXCAN_RERRSYNR_BE1_MASK (0x8000U) +#define FLEXCAN_RERRSYNR_BE1_SHIFT (15U) +#define FLEXCAN_RERRSYNR_BE1_WIDTH (1U) +#define FLEXCAN_RERRSYNR_BE1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRSYNR_BE1_SHIFT)) & FLEXCAN_RERRSYNR_BE1_MASK) + +#define FLEXCAN_RERRSYNR_SYND2_MASK (0x1F0000U) +#define FLEXCAN_RERRSYNR_SYND2_SHIFT (16U) +#define FLEXCAN_RERRSYNR_SYND2_WIDTH (5U) +#define FLEXCAN_RERRSYNR_SYND2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRSYNR_SYND2_SHIFT)) & FLEXCAN_RERRSYNR_SYND2_MASK) + +#define FLEXCAN_RERRSYNR_BE2_MASK (0x800000U) +#define FLEXCAN_RERRSYNR_BE2_SHIFT (23U) +#define FLEXCAN_RERRSYNR_BE2_WIDTH (1U) +#define FLEXCAN_RERRSYNR_BE2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRSYNR_BE2_SHIFT)) & FLEXCAN_RERRSYNR_BE2_MASK) + +#define FLEXCAN_RERRSYNR_SYND3_MASK (0x1F000000U) +#define FLEXCAN_RERRSYNR_SYND3_SHIFT (24U) +#define FLEXCAN_RERRSYNR_SYND3_WIDTH (5U) +#define FLEXCAN_RERRSYNR_SYND3(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRSYNR_SYND3_SHIFT)) & FLEXCAN_RERRSYNR_SYND3_MASK) + +#define FLEXCAN_RERRSYNR_BE3_MASK (0x80000000U) +#define FLEXCAN_RERRSYNR_BE3_SHIFT (31U) +#define FLEXCAN_RERRSYNR_BE3_WIDTH (1U) +#define FLEXCAN_RERRSYNR_BE3(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_RERRSYNR_BE3_SHIFT)) & FLEXCAN_RERRSYNR_BE3_MASK) + +#define FLEXCAN_ERRSR_CEIOF_MASK (0x1U) +#define FLEXCAN_ERRSR_CEIOF_SHIFT (0U) +#define FLEXCAN_ERRSR_CEIOF_WIDTH (1U) +#define FLEXCAN_ERRSR_CEIOF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRSR_CEIOF_SHIFT)) & FLEXCAN_ERRSR_CEIOF_MASK) + +#define FLEXCAN_ERRSR_FANCEIOF_MASK (0x4U) +#define FLEXCAN_ERRSR_FANCEIOF_SHIFT (2U) +#define FLEXCAN_ERRSR_FANCEIOF_WIDTH (1U) +#define FLEXCAN_ERRSR_FANCEIOF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRSR_FANCEIOF_SHIFT)) & FLEXCAN_ERRSR_FANCEIOF_MASK) + +#define FLEXCAN_ERRSR_HANCEIOF_MASK (0x8U) +#define FLEXCAN_ERRSR_HANCEIOF_SHIFT (3U) +#define FLEXCAN_ERRSR_HANCEIOF_WIDTH (1U) +#define FLEXCAN_ERRSR_HANCEIOF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRSR_HANCEIOF_SHIFT)) & FLEXCAN_ERRSR_HANCEIOF_MASK) + +#define FLEXCAN_ERRSR_CEIF_MASK (0x10000U) +#define FLEXCAN_ERRSR_CEIF_SHIFT (16U) +#define FLEXCAN_ERRSR_CEIF_WIDTH (1U) +#define FLEXCAN_ERRSR_CEIF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRSR_CEIF_SHIFT)) & FLEXCAN_ERRSR_CEIF_MASK) + +#define FLEXCAN_ERRSR_FANCEIF_MASK (0x40000U) +#define FLEXCAN_ERRSR_FANCEIF_SHIFT (18U) +#define FLEXCAN_ERRSR_FANCEIF_WIDTH (1U) +#define FLEXCAN_ERRSR_FANCEIF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRSR_FANCEIF_SHIFT)) & FLEXCAN_ERRSR_FANCEIF_MASK) + +#define FLEXCAN_ERRSR_HANCEIF_MASK (0x80000U) +#define FLEXCAN_ERRSR_HANCEIF_SHIFT (19U) +#define FLEXCAN_ERRSR_HANCEIF_WIDTH (1U) +#define FLEXCAN_ERRSR_HANCEIF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERRSR_HANCEIF_SHIFT)) & FLEXCAN_ERRSR_HANCEIF_MASK) + +#define FLEXCAN_EPRS_ENPRESDIV_MASK (0x3FFU) +#define FLEXCAN_EPRS_ENPRESDIV_SHIFT (0U) +#define FLEXCAN_EPRS_ENPRESDIV_WIDTH (10U) +#define FLEXCAN_EPRS_ENPRESDIV(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_EPRS_ENPRESDIV_SHIFT)) & FLEXCAN_EPRS_ENPRESDIV_MASK) + +#define FLEXCAN_EPRS_EDPRESDIV_MASK (0x3FF0000U) +#define FLEXCAN_EPRS_EDPRESDIV_SHIFT (16U) +#define FLEXCAN_EPRS_EDPRESDIV_WIDTH (10U) +#define FLEXCAN_EPRS_EDPRESDIV(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_EPRS_EDPRESDIV_SHIFT)) & FLEXCAN_EPRS_EDPRESDIV_MASK) + +#define FLEXCAN_ENCBT_NTSEG1_MASK (0xFFU) +#define FLEXCAN_ENCBT_NTSEG1_SHIFT (0U) +#define FLEXCAN_ENCBT_NTSEG1_WIDTH (8U) +#define FLEXCAN_ENCBT_NTSEG1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ENCBT_NTSEG1_SHIFT)) & FLEXCAN_ENCBT_NTSEG1_MASK) + +#define FLEXCAN_ENCBT_NTSEG2_MASK (0x7F000U) +#define FLEXCAN_ENCBT_NTSEG2_SHIFT (12U) +#define FLEXCAN_ENCBT_NTSEG2_WIDTH (7U) +#define FLEXCAN_ENCBT_NTSEG2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ENCBT_NTSEG2_SHIFT)) & FLEXCAN_ENCBT_NTSEG2_MASK) + +#define FLEXCAN_ENCBT_NRJW_MASK (0x1FC00000U) +#define FLEXCAN_ENCBT_NRJW_SHIFT (22U) +#define FLEXCAN_ENCBT_NRJW_WIDTH (7U) +#define FLEXCAN_ENCBT_NRJW(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ENCBT_NRJW_SHIFT)) & FLEXCAN_ENCBT_NRJW_MASK) + +#define FLEXCAN_EDCBT_DTSEG1_MASK (0x1FU) +#define FLEXCAN_EDCBT_DTSEG1_SHIFT (0U) +#define FLEXCAN_EDCBT_DTSEG1_WIDTH (5U) +#define FLEXCAN_EDCBT_DTSEG1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_EDCBT_DTSEG1_SHIFT)) & FLEXCAN_EDCBT_DTSEG1_MASK) + +#define FLEXCAN_EDCBT_DTSEG2_MASK (0xF000U) +#define FLEXCAN_EDCBT_DTSEG2_SHIFT (12U) +#define FLEXCAN_EDCBT_DTSEG2_WIDTH (4U) +#define FLEXCAN_EDCBT_DTSEG2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_EDCBT_DTSEG2_SHIFT)) & FLEXCAN_EDCBT_DTSEG2_MASK) + +#define FLEXCAN_EDCBT_DRJW_MASK (0x3C00000U) +#define FLEXCAN_EDCBT_DRJW_SHIFT (22U) +#define FLEXCAN_EDCBT_DRJW_WIDTH (4U) +#define FLEXCAN_EDCBT_DRJW(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_EDCBT_DRJW_SHIFT)) & FLEXCAN_EDCBT_DRJW_MASK) + +#define FLEXCAN_ETDC_ETDCVAL_MASK (0xFFU) +#define FLEXCAN_ETDC_ETDCVAL_SHIFT (0U) +#define FLEXCAN_ETDC_ETDCVAL_WIDTH (8U) +#define FLEXCAN_ETDC_ETDCVAL(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ETDC_ETDCVAL_SHIFT)) & FLEXCAN_ETDC_ETDCVAL_MASK) + +#define FLEXCAN_ETDC_ETDCFAIL_MASK (0x8000U) +#define FLEXCAN_ETDC_ETDCFAIL_SHIFT (15U) +#define FLEXCAN_ETDC_ETDCFAIL_WIDTH (1U) +#define FLEXCAN_ETDC_ETDCFAIL(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ETDC_ETDCFAIL_SHIFT)) & FLEXCAN_ETDC_ETDCFAIL_MASK) + +#define FLEXCAN_ETDC_ETDCOFF_MASK (0x7F0000U) +#define FLEXCAN_ETDC_ETDCOFF_SHIFT (16U) +#define FLEXCAN_ETDC_ETDCOFF_WIDTH (7U) +#define FLEXCAN_ETDC_ETDCOFF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ETDC_ETDCOFF_SHIFT)) & FLEXCAN_ETDC_ETDCOFF_MASK) + +#define FLEXCAN_ETDC_TDMDIS_MASK (0x40000000U) +#define FLEXCAN_ETDC_TDMDIS_SHIFT (30U) +#define FLEXCAN_ETDC_TDMDIS_WIDTH (1U) +#define FLEXCAN_ETDC_TDMDIS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ETDC_TDMDIS_SHIFT)) & FLEXCAN_ETDC_TDMDIS_MASK) + +#define FLEXCAN_ETDC_ETDCEN_MASK (0x80000000U) +#define FLEXCAN_ETDC_ETDCEN_SHIFT (31U) +#define FLEXCAN_ETDC_ETDCEN_WIDTH (1U) +#define FLEXCAN_ETDC_ETDCEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ETDC_ETDCEN_SHIFT)) & FLEXCAN_ETDC_ETDCEN_MASK) + +#define FLEXCAN_FDCTRL_TDCVAL_MASK (0x3FU) +#define FLEXCAN_FDCTRL_TDCVAL_SHIFT (0U) +#define FLEXCAN_FDCTRL_TDCVAL_WIDTH (6U) +#define FLEXCAN_FDCTRL_TDCVAL(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_TDCVAL_SHIFT)) & FLEXCAN_FDCTRL_TDCVAL_MASK) + +#define FLEXCAN_FDCTRL_TDCOFF_MASK (0x1F00U) +#define FLEXCAN_FDCTRL_TDCOFF_SHIFT (8U) +#define FLEXCAN_FDCTRL_TDCOFF_WIDTH (5U) +#define FLEXCAN_FDCTRL_TDCOFF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_TDCOFF_SHIFT)) & FLEXCAN_FDCTRL_TDCOFF_MASK) + +#define FLEXCAN_FDCTRL_TDCFAIL_MASK (0x4000U) +#define FLEXCAN_FDCTRL_TDCFAIL_SHIFT (14U) +#define FLEXCAN_FDCTRL_TDCFAIL_WIDTH (1U) +#define FLEXCAN_FDCTRL_TDCFAIL(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_TDCFAIL_SHIFT)) & FLEXCAN_FDCTRL_TDCFAIL_MASK) + +#define FLEXCAN_FDCTRL_TDCEN_MASK (0x8000U) +#define FLEXCAN_FDCTRL_TDCEN_SHIFT (15U) +#define FLEXCAN_FDCTRL_TDCEN_WIDTH (1U) +#define FLEXCAN_FDCTRL_TDCEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_TDCEN_SHIFT)) & FLEXCAN_FDCTRL_TDCEN_MASK) + +#define FLEXCAN_FDCTRL_MBDSR0_MASK (0x30000U) +#define FLEXCAN_FDCTRL_MBDSR0_SHIFT (16U) +#define FLEXCAN_FDCTRL_MBDSR0_WIDTH (2U) +#define FLEXCAN_FDCTRL_MBDSR0(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_MBDSR0_SHIFT)) & FLEXCAN_FDCTRL_MBDSR0_MASK) + +#define FLEXCAN_FDCTRL_MBDSR1_MASK (0x180000U) +#define FLEXCAN_FDCTRL_MBDSR1_SHIFT (19U) +#define FLEXCAN_FDCTRL_MBDSR1_WIDTH (2U) +#define FLEXCAN_FDCTRL_MBDSR1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_MBDSR1_SHIFT)) & FLEXCAN_FDCTRL_MBDSR1_MASK) + +#define FLEXCAN_FDCTRL_MBDSR2_MASK (0xC00000U) +#define FLEXCAN_FDCTRL_MBDSR2_SHIFT (22U) +#define FLEXCAN_FDCTRL_MBDSR2_WIDTH (2U) +#define FLEXCAN_FDCTRL_MBDSR2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_MBDSR2_SHIFT)) & FLEXCAN_FDCTRL_MBDSR2_MASK) + +#define FLEXCAN_FDCTRL_MBDSR3_MASK (0x6000000U) +#define FLEXCAN_FDCTRL_MBDSR3_SHIFT (25U) +#define FLEXCAN_FDCTRL_MBDSR3_WIDTH (2U) +#define FLEXCAN_FDCTRL_MBDSR3(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_MBDSR3_SHIFT)) & FLEXCAN_FDCTRL_MBDSR3_MASK) + +#define FLEXCAN_FDCTRL_FDRATE_MASK (0x80000000U) +#define FLEXCAN_FDCTRL_FDRATE_SHIFT (31U) +#define FLEXCAN_FDCTRL_FDRATE_WIDTH (1U) +#define FLEXCAN_FDCTRL_FDRATE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCTRL_FDRATE_SHIFT)) & FLEXCAN_FDCTRL_FDRATE_MASK) + +#define FLEXCAN_FDCBT_FPSEG2_MASK (0x7U) +#define FLEXCAN_FDCBT_FPSEG2_SHIFT (0U) +#define FLEXCAN_FDCBT_FPSEG2_WIDTH (3U) +#define FLEXCAN_FDCBT_FPSEG2(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCBT_FPSEG2_SHIFT)) & FLEXCAN_FDCBT_FPSEG2_MASK) + +#define FLEXCAN_FDCBT_FPSEG1_MASK (0xE0U) +#define FLEXCAN_FDCBT_FPSEG1_SHIFT (5U) +#define FLEXCAN_FDCBT_FPSEG1_WIDTH (3U) +#define FLEXCAN_FDCBT_FPSEG1(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCBT_FPSEG1_SHIFT)) & FLEXCAN_FDCBT_FPSEG1_MASK) + +#define FLEXCAN_FDCBT_FPROPSEG_MASK (0x7C00U) +#define FLEXCAN_FDCBT_FPROPSEG_SHIFT (10U) +#define FLEXCAN_FDCBT_FPROPSEG_WIDTH (5U) +#define FLEXCAN_FDCBT_FPROPSEG(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCBT_FPROPSEG_SHIFT)) & FLEXCAN_FDCBT_FPROPSEG_MASK) + +#define FLEXCAN_FDCBT_FRJW_MASK (0x70000U) +#define FLEXCAN_FDCBT_FRJW_SHIFT (16U) +#define FLEXCAN_FDCBT_FRJW_WIDTH (3U) +#define FLEXCAN_FDCBT_FRJW(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCBT_FRJW_SHIFT)) & FLEXCAN_FDCBT_FRJW_MASK) + +#define FLEXCAN_FDCBT_FPRESDIV_MASK (0x3FF00000U) +#define FLEXCAN_FDCBT_FPRESDIV_SHIFT (20U) +#define FLEXCAN_FDCBT_FPRESDIV_WIDTH (10U) +#define FLEXCAN_FDCBT_FPRESDIV(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCBT_FPRESDIV_SHIFT)) & FLEXCAN_FDCBT_FPRESDIV_MASK) + +#define FLEXCAN_FDCRC_FD_TXCRC_MASK (0x1FFFFFU) +#define FLEXCAN_FDCRC_FD_TXCRC_SHIFT (0U) +#define FLEXCAN_FDCRC_FD_TXCRC_WIDTH (21U) +#define FLEXCAN_FDCRC_FD_TXCRC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCRC_FD_TXCRC_SHIFT)) & FLEXCAN_FDCRC_FD_TXCRC_MASK) + +#define FLEXCAN_FDCRC_FD_MBCRC_MASK (0x7F000000U) +#define FLEXCAN_FDCRC_FD_MBCRC_SHIFT (24U) +#define FLEXCAN_FDCRC_FD_MBCRC_WIDTH (7U) +#define FLEXCAN_FDCRC_FD_MBCRC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_FDCRC_FD_MBCRC_SHIFT)) & FLEXCAN_FDCRC_FD_MBCRC_MASK) + +#define FLEXCAN_ERFCR_ERFWM_MASK (0x1FU) +#define FLEXCAN_ERFCR_ERFWM_SHIFT (0U) +#define FLEXCAN_ERFCR_ERFWM_WIDTH (5U) +#define FLEXCAN_ERFCR_ERFWM(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFCR_ERFWM_SHIFT)) & FLEXCAN_ERFCR_ERFWM_MASK) + +#define FLEXCAN_ERFCR_NFE_MASK (0x3F00U) +#define FLEXCAN_ERFCR_NFE_SHIFT (8U) +#define FLEXCAN_ERFCR_NFE_WIDTH (6U) +#define FLEXCAN_ERFCR_NFE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFCR_NFE_SHIFT)) & FLEXCAN_ERFCR_NFE_MASK) + +#define FLEXCAN_ERFCR_NEXIF_MASK (0x7F0000U) +#define FLEXCAN_ERFCR_NEXIF_SHIFT (16U) +#define FLEXCAN_ERFCR_NEXIF_WIDTH (7U) +#define FLEXCAN_ERFCR_NEXIF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFCR_NEXIF_SHIFT)) & FLEXCAN_ERFCR_NEXIF_MASK) + +#define FLEXCAN_ERFCR_DMALW_MASK (0x7C000000U) +#define FLEXCAN_ERFCR_DMALW_SHIFT (26U) +#define FLEXCAN_ERFCR_DMALW_WIDTH (5U) +#define FLEXCAN_ERFCR_DMALW(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFCR_DMALW_SHIFT)) & FLEXCAN_ERFCR_DMALW_MASK) + +#define FLEXCAN_ERFCR_ERFEN_MASK (0x80000000U) +#define FLEXCAN_ERFCR_ERFEN_SHIFT (31U) +#define FLEXCAN_ERFCR_ERFEN_WIDTH (1U) +#define FLEXCAN_ERFCR_ERFEN(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFCR_ERFEN_SHIFT)) & FLEXCAN_ERFCR_ERFEN_MASK) + +#define FLEXCAN_ERFIER_ERFDAIE_MASK (0x10000000U) +#define FLEXCAN_ERFIER_ERFDAIE_SHIFT (28U) +#define FLEXCAN_ERFIER_ERFDAIE_WIDTH (1U) +#define FLEXCAN_ERFIER_ERFDAIE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFIER_ERFDAIE_SHIFT)) & FLEXCAN_ERFIER_ERFDAIE_MASK) + +#define FLEXCAN_ERFIER_ERFWMIIE_MASK (0x20000000U) +#define FLEXCAN_ERFIER_ERFWMIIE_SHIFT (29U) +#define FLEXCAN_ERFIER_ERFWMIIE_WIDTH (1U) +#define FLEXCAN_ERFIER_ERFWMIIE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFIER_ERFWMIIE_SHIFT)) & FLEXCAN_ERFIER_ERFWMIIE_MASK) + +#define FLEXCAN_ERFIER_ERFOVFIE_MASK (0x40000000U) +#define FLEXCAN_ERFIER_ERFOVFIE_SHIFT (30U) +#define FLEXCAN_ERFIER_ERFOVFIE_WIDTH (1U) +#define FLEXCAN_ERFIER_ERFOVFIE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFIER_ERFOVFIE_SHIFT)) & FLEXCAN_ERFIER_ERFOVFIE_MASK) + +#define FLEXCAN_ERFIER_ERFUFWIE_MASK (0x80000000U) +#define FLEXCAN_ERFIER_ERFUFWIE_SHIFT (31U) +#define FLEXCAN_ERFIER_ERFUFWIE_WIDTH (1U) +#define FLEXCAN_ERFIER_ERFUFWIE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFIER_ERFUFWIE_SHIFT)) & FLEXCAN_ERFIER_ERFUFWIE_MASK) + +#define FLEXCAN_ERFSR_ERFEL_MASK (0x3FU) +#define FLEXCAN_ERFSR_ERFEL_SHIFT (0U) +#define FLEXCAN_ERFSR_ERFEL_WIDTH (6U) +#define FLEXCAN_ERFSR_ERFEL(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFSR_ERFEL_SHIFT)) & FLEXCAN_ERFSR_ERFEL_MASK) + +#define FLEXCAN_ERFSR_ERFF_MASK (0x10000U) +#define FLEXCAN_ERFSR_ERFF_SHIFT (16U) +#define FLEXCAN_ERFSR_ERFF_WIDTH (1U) +#define FLEXCAN_ERFSR_ERFF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFSR_ERFF_SHIFT)) & FLEXCAN_ERFSR_ERFF_MASK) + +#define FLEXCAN_ERFSR_ERFE_MASK (0x20000U) +#define FLEXCAN_ERFSR_ERFE_SHIFT (17U) +#define FLEXCAN_ERFSR_ERFE_WIDTH (1U) +#define FLEXCAN_ERFSR_ERFE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFSR_ERFE_SHIFT)) & FLEXCAN_ERFSR_ERFE_MASK) + +#define FLEXCAN_ERFSR_ERFCLR_MASK (0x8000000U) +#define FLEXCAN_ERFSR_ERFCLR_SHIFT (27U) +#define FLEXCAN_ERFSR_ERFCLR_WIDTH (1U) +#define FLEXCAN_ERFSR_ERFCLR(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFSR_ERFCLR_SHIFT)) & FLEXCAN_ERFSR_ERFCLR_MASK) + +#define FLEXCAN_ERFSR_ERFDA_MASK (0x10000000U) +#define FLEXCAN_ERFSR_ERFDA_SHIFT (28U) +#define FLEXCAN_ERFSR_ERFDA_WIDTH (1U) +#define FLEXCAN_ERFSR_ERFDA(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFSR_ERFDA_SHIFT)) & FLEXCAN_ERFSR_ERFDA_MASK) + +#define FLEXCAN_ERFSR_ERFWMI_MASK (0x20000000U) +#define FLEXCAN_ERFSR_ERFWMI_SHIFT (29U) +#define FLEXCAN_ERFSR_ERFWMI_WIDTH (1U) +#define FLEXCAN_ERFSR_ERFWMI(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFSR_ERFWMI_SHIFT)) & FLEXCAN_ERFSR_ERFWMI_MASK) + +#define FLEXCAN_ERFSR_ERFOVF_MASK (0x40000000U) +#define FLEXCAN_ERFSR_ERFOVF_SHIFT (30U) +#define FLEXCAN_ERFSR_ERFOVF_WIDTH (1U) +#define FLEXCAN_ERFSR_ERFOVF(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFSR_ERFOVF_SHIFT)) & FLEXCAN_ERFSR_ERFOVF_MASK) + +#define FLEXCAN_ERFSR_ERFUFW_MASK (0x80000000U) +#define FLEXCAN_ERFSR_ERFUFW_SHIFT (31U) +#define FLEXCAN_ERFSR_ERFUFW_WIDTH (1U) +#define FLEXCAN_ERFSR_ERFUFW(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFSR_ERFUFW_SHIFT)) & FLEXCAN_ERFSR_ERFUFW_MASK) + +#define FLEXCAN_HR_TIME_STAMP_TS_MASK (0xFFFFFFFFU) +#define FLEXCAN_HR_TIME_STAMP_TS_SHIFT (0U) +#define FLEXCAN_HR_TIME_STAMP_TS_WIDTH (32U) +#define FLEXCAN_HR_TIME_STAMP_TS(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_HR_TIME_STAMP_TS_SHIFT)) & FLEXCAN_HR_TIME_STAMP_TS_MASK) + +#define FLEXCAN_ERFFEL_FEL_MASK (0xFFFFFFFFU) +#define FLEXCAN_ERFFEL_FEL_SHIFT (0U) +#define FLEXCAN_ERFFEL_FEL_WIDTH (32U) +#define FLEXCAN_ERFFEL_FEL(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_ERFFEL_FEL_SHIFT)) & FLEXCAN_ERFFEL_FEL_MASK) + +#define FLEXCAN_TSCTRL_REFRESH_MASK (0x8U) +#define FLEXCAN_TSCTRL_REFRESH_SHIFT (3U) +#define FLEXCAN_TSCTRL_REFRESH_WIDTH (1U) +#define FLEXCAN_TSCTRL_REFRESH(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_TSCTRL_REFRESH_SHIFT)) & FLEXCAN_TSCTRL_REFRESH_MASK) + +#define FLEXCAN_TSCTRL_SRC_MASK (0x10U) +#define FLEXCAN_TSCTRL_SRC_SHIFT (4U) +#define FLEXCAN_TSCTRL_SRC_WIDTH (1U) +#define FLEXCAN_TSCTRL_SRC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_TSCTRL_SRC_SHIFT)) & FLEXCAN_TSCTRL_SRC_MASK) + +#define FLEXCAN_TSCTRL_PSLVE_MASK (0x20U) +#define FLEXCAN_TSCTRL_PSLVE_SHIFT (5U) +#define FLEXCAN_TSCTRL_PSLVE_WIDTH (1U) +#define FLEXCAN_TSCTRL_PSLVE(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_TSCTRL_PSLVE_SHIFT)) & FLEXCAN_TSCTRL_PSLVE_MASK) + + +/* Default value for register */ +/** +* @brief Default value for the MCR register +*/ +#define FLEXCAN_IP_MCR_DEFAULT_VALUE_U32 ((rt_uint32_t)0xD890000FU) + +/** +* @brief Default value for the CTRL1 register +*/ +#define FLEXCAN_IP_CTRL1_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the TIMER register +*/ +#define FLEXCAN_IP_TIMER_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ECR register +*/ +#define FLEXCAN_IP_ECR_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ESR1 register +*/ +#define FLEXCAN_IP_ESR1_DEFAULT_VALUE_U32 ((rt_uint32_t)0x003B0006U) + +/** +* @brief Default value for the IMASKx register +*/ +#define FLEXCAN_IP_IMASK_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the IFLAG4 register +*/ +#define FLEXCAN_IP_IFLAG_DEFAULT_VALUE_U32 ((rt_uint32_t)0xFFFFFFFFU) + +/** +* @brief Default value for the CTRL2 register +*/ +#define FLEXCAN_IP_CTRL2_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00100000U) + +/** +* @brief Default value for the CTRL2 register +*/ +#define FLEXCAN_IP_CBT_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the MECR register +*/ +#define FLEXCAN_IP_MECR_DEFAULT_VALUE_U32 ((rt_uint32_t)0x000C0080U) + +/** +* @brief Default value for the ERRIAR register +*/ +#define FLEXCAN_IP_ERRIAR_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ERRIDPR register +*/ +#define FLEXCAN_IP_ERRIDPR_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ERRIPPR register +*/ +#define FLEXCAN_IP_ERRIPPR_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ERRSR register +*/ +#define FLEXCAN_IP_ERRSR_DEFAULT_VALUE_U32 ((rt_uint32_t)0x000D000DU) + +/** +* @brief Default value for the FDCTRL register +*/ +#define FLEXCAN_IP_FDCTRL_DEFAULT_VALUE_U32 ((rt_uint32_t)0x80004100U) + +/** +* @brief Default value for the FDCBT register +*/ +#define FLEXCAN_IP_FDCBT_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ERFCR register +*/ +#define FLEXCAN_IP_ERFCR_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ERFIER register +*/ +#define FLEXCAN_IP_ERFIER_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ERFSR register +*/ +#define FLEXCAN_IP_ERFSR_DEFAULT_VALUE_U32 ((rt_uint32_t)0xF8000000U) + +/** +* @brief Default value for the EPRS register +*/ +#define FLEXCAN_IP_EPRS_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ENCBT register +*/ +#define FLEXCAN_IP_ENCBT_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the EDCBT register +*/ +#define FLEXCAN_IP_EDCBT_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/** +* @brief Default value for the ETDC register +*/ +#define FLEXCAN_IP_ETDC_DEFAULT_VALUE_U32 ((rt_uint32_t)0x00000000U) + +/* @brief number of CAN peripheral has Enhanced Rx FIFO mode */ +#define FLEXCAN_IP_FEATURE_ENHANCED_RX_FIFO_NUM (10U) + +/* @brief number of CAN peripheral has expandable memory */ +#define FLEXCAN_IP_FEATURE_EXPANDABLE_MEMORY_NUM (6U) + +#endif diff --git a/bsp/rdk/s100/drivers/drv_gpio.c b/bsp/rdk/s100/drivers/drv_gpio.c new file mode 100644 index 00000000000..6109e67d0d4 --- /dev/null +++ b/bsp/rdk/s100/drivers/drv_gpio.c @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ + +#include + +#include "drv_gpio.h" +#include "interrupt.h" + + +#define S100_GPIO_PORT0_BASE 0x23480000U +#define S100_GPIO_PORT1_BASE 0x23490000U +#define S100_GPIO_PORT2_BASE 0x234A0000U + +#define S100_GPIO_PORT0_IRQ 68 +#define S100_GPIO_PORT1_IRQ 69 +#define S100_GPIO_PORT2_IRQ 70 + +#define S100_GPIO_PORT_COUNT 3 +#define S100_GPIO_CHANNELS_PER_PORT 32 + +typedef struct +{ + volatile rt_uint32_t swporta_dr; + volatile rt_uint32_t swporta_ddr; + volatile rt_uint32_t rsvd0; + volatile rt_uint32_t swportb_dr; + volatile rt_uint32_t swportb_ddr; + volatile rt_uint32_t rsvd1[7]; + volatile rt_uint32_t inten; + volatile rt_uint32_t intmask; + volatile rt_uint32_t inttype_level; + volatile rt_uint32_t int_polarity; + volatile rt_uint32_t intstatus; + volatile rt_uint32_t raw_intstatus; + volatile rt_uint32_t debounce; + volatile rt_uint32_t porta_eoi; + volatile rt_uint32_t ext_porta; + volatile rt_uint32_t ext_portb; + volatile rt_uint32_t rsvd2[2]; + volatile rt_uint32_t ls_sync; + volatile rt_uint32_t id_code; + volatile rt_uint32_t int_bothedge; + volatile rt_uint32_t ver_id_code; +} s100_gpio_reg_t; + +static s100_gpio_reg_t *const s100_gpio_ports[S100_GPIO_PORT_COUNT] = +{ + (s100_gpio_reg_t *)S100_GPIO_PORT0_BASE, + (s100_gpio_reg_t *)S100_GPIO_PORT1_BASE, + (s100_gpio_reg_t *)S100_GPIO_PORT2_BASE, +}; + +static const int s100_gpio_port_irqs[S100_GPIO_PORT_COUNT] = +{ + S100_GPIO_PORT0_IRQ, + S100_GPIO_PORT1_IRQ, + S100_GPIO_PORT2_IRQ, +}; + +static struct rt_pin_irq_hdr s100_pin_irq_hdr[S100_GPIO_PIN_COUNT]; + +static rt_err_t s100_pin_to_gpio(s100_pin_t pin, + rt_uint8_t *port_index, + rt_uint8_t *bit_index) +{ + rt_uint8_t gpio_pin; + + if (!s100_pin_is_valid(pin)) + { + return -RT_EINVAL; + } + + /* The MCU GPIO numbering skips pin 79, so pins >= 80 shift by one. */ + gpio_pin = (pin >= 80U) ? (pin - 1U) : pin; + *port_index = gpio_pin / S100_GPIO_CHANNELS_PER_PORT; + *bit_index = gpio_pin % S100_GPIO_CHANNELS_PER_PORT; + + if (*port_index >= S100_GPIO_PORT_COUNT) + { + return -RT_EINVAL; + } + + return RT_EOK; +} + +static rt_err_t s100_gpio_to_pin(rt_uint8_t port_index, + rt_uint8_t bit_index, + s100_pin_t *pin) +{ + rt_uint8_t gpio_pin; + + if (port_index >= S100_GPIO_PORT_COUNT || bit_index >= S100_GPIO_CHANNELS_PER_PORT) + { + return -RT_EINVAL; + } + + gpio_pin = (port_index * S100_GPIO_CHANNELS_PER_PORT) + bit_index; + *pin = (gpio_pin >= 79U) ? (gpio_pin + 1U) : gpio_pin; + + if (!s100_pin_is_valid(*pin)) + { + return -RT_EINVAL; + } + + return RT_EOK; +} + +static rt_err_t s100_gpio_config_irq(rt_base_t pin, rt_uint8_t mode) +{ + rt_uint8_t port_index; + rt_uint8_t bit_index; + rt_uint32_t bit; + s100_gpio_reg_t *gpio; + rt_err_t ret; + + ret = s100_pin_to_gpio((s100_pin_t)pin, &port_index, &bit_index); + if (ret != RT_EOK) + { + return ret; + } + + gpio = s100_gpio_ports[port_index]; + bit = 1UL << bit_index; + + gpio->inten &= ~bit; + gpio->intmask |= bit; + gpio->int_bothedge &= ~bit; + + switch (mode) + { + case PIN_IRQ_MODE_RISING: + gpio->inttype_level |= bit; + gpio->int_polarity |= bit; + break; + case PIN_IRQ_MODE_FALLING: + gpio->inttype_level |= bit; + gpio->int_polarity &= ~bit; + break; + case PIN_IRQ_MODE_RISING_FALLING: + gpio->inttype_level |= bit; + gpio->int_bothedge |= bit; + break; + case PIN_IRQ_MODE_HIGH_LEVEL: + gpio->inttype_level &= ~bit; + gpio->int_polarity |= bit; + break; + case PIN_IRQ_MODE_LOW_LEVEL: + gpio->inttype_level &= ~bit; + gpio->int_polarity &= ~bit; + break; + default: + return -RT_EINVAL; + } + + gpio->porta_eoi = bit; + return RT_EOK; +} + +rt_err_t s100_gpio_set_direction(s100_pin_t pin, s100_pin_direction_t direction) +{ + rt_uint8_t port_index; + rt_uint8_t bit_index; + rt_uint32_t bit; + rt_err_t ret; + + ret = s100_pin_to_gpio(pin, &port_index, &bit_index); + if (ret != RT_EOK) + { + return -RT_EINVAL; + } + + bit = 1UL << bit_index; + if (direction == S100_PIN_DIR_OUT) + { + s100_gpio_ports[port_index]->swporta_ddr |= bit; + } + else + { + s100_gpio_ports[port_index]->swporta_ddr &= ~bit; + } + + return RT_EOK; +} + +rt_err_t s100_gpio_write_pin(s100_pin_t pin, s100_pin_level_t level) +{ + rt_uint8_t port_index; + rt_uint8_t bit_index; + rt_uint32_t bit; + rt_err_t ret; + + ret = s100_pin_to_gpio(pin, &port_index, &bit_index); + if (ret != RT_EOK) + { + return -RT_EINVAL; + } + + bit = 1UL << bit_index; + if (level == S100_PIN_LEVEL_HIGH) + { + s100_gpio_ports[port_index]->swporta_dr |= bit; + } + else + { + s100_gpio_ports[port_index]->swporta_dr &= ~bit; + } + + return RT_EOK; +} + +rt_err_t s100_gpio_read_pin(s100_pin_t pin, s100_pin_level_t *level) +{ + rt_uint8_t port_index; + rt_uint8_t bit_index; + rt_err_t ret; + + if (level == RT_NULL) + { + return -RT_EINVAL; + } + + ret = s100_pin_to_gpio(pin, &port_index, &bit_index); + if (ret != RT_EOK) + { + return -RT_EINVAL; + } + + *level = (s100_gpio_ports[port_index]->ext_porta & (1UL << bit_index)) ? + S100_PIN_LEVEL_HIGH : S100_PIN_LEVEL_LOW; + + return RT_EOK; +} + +void s100_gpio_write(rt_uint8_t pin, rt_uint8_t value) +{ + (void)s100_pin_set_function(pin, S100_PIN_FUNC_GPIO); + (void)s100_gpio_set_direction(pin, S100_PIN_DIR_OUT); + (void)s100_gpio_write_pin(pin, value ? S100_PIN_LEVEL_HIGH : S100_PIN_LEVEL_LOW); +} + +rt_uint8_t s100_gpio_read(rt_uint8_t pin) +{ + s100_pin_level_t level = S100_PIN_LEVEL_LOW; + + (void)s100_gpio_read_pin(pin, &level); + return (level == S100_PIN_LEVEL_HIGH) ? 1U : 0U; +} + +static void s100_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode) +{ + RT_UNUSED(device); + + switch (mode) + { + case PIN_MODE_OUTPUT: + (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO); + (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_OUT); + break; + case PIN_MODE_INPUT: + (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO); + (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_IN); + (void)s100_pin_set_pull((s100_pin_t)pin, S100_PIN_PULL_NONE); + break; + case PIN_MODE_INPUT_PULLUP: + (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO); + (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_IN); + (void)s100_pin_set_pull((s100_pin_t)pin, S100_PIN_PULL_UP); + break; + case PIN_MODE_INPUT_PULLDOWN: + (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO); + (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_IN); + (void)s100_pin_set_pull((s100_pin_t)pin, S100_PIN_PULL_DOWN); + break; + case PIN_MODE_OUTPUT_OD: + (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO); + (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_OUT); + (void)s100_pin_set_pull((s100_pin_t)pin, S100_PIN_PULL_UP); + break; + default: + break; + } +} + +static void s100_pin_write_device(struct rt_device *device, rt_base_t pin, rt_uint8_t value) +{ + RT_UNUSED(device); + (void)s100_gpio_write_pin((s100_pin_t)pin, + value ? S100_PIN_LEVEL_HIGH : S100_PIN_LEVEL_LOW); +} + +static rt_ssize_t s100_pin_read_device(struct rt_device *device, rt_base_t pin) +{ + s100_pin_level_t level = S100_PIN_LEVEL_LOW; + + RT_UNUSED(device); + if (s100_gpio_read_pin((s100_pin_t)pin, &level) != RT_EOK) + { + return PIN_LOW; + } + + return (level == S100_PIN_LEVEL_HIGH) ? PIN_HIGH : PIN_LOW; +} + +static rt_err_t s100_pin_attach_irq(struct rt_device *device, + rt_base_t pin, + rt_uint8_t mode, + void (*hdr)(void *args), + void *args) +{ + rt_base_t level; + + RT_UNUSED(device); + if (!s100_pin_is_valid((s100_pin_t)pin)) + { + return -RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + s100_pin_irq_hdr[pin].pin = pin; + s100_pin_irq_hdr[pin].mode = mode; + s100_pin_irq_hdr[pin].hdr = hdr; + s100_pin_irq_hdr[pin].args = args; + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +static rt_err_t s100_pin_detach_irq(struct rt_device *device, rt_base_t pin) +{ + rt_base_t level; + + RT_UNUSED(device); + if (!s100_pin_is_valid((s100_pin_t)pin)) + { + return -RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + s100_pin_irq_hdr[pin].pin = -1; + s100_pin_irq_hdr[pin].mode = 0; + s100_pin_irq_hdr[pin].hdr = RT_NULL; + s100_pin_irq_hdr[pin].args = RT_NULL; + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +static rt_err_t s100_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled) +{ + rt_uint8_t port_index; + rt_uint8_t bit_index; + rt_uint32_t bit; + s100_gpio_reg_t *gpio; + rt_err_t ret; + + RT_UNUSED(device); + ret = s100_pin_to_gpio((s100_pin_t)pin, &port_index, &bit_index); + if (ret != RT_EOK) + { + return ret; + } + + gpio = s100_gpio_ports[port_index]; + bit = 1UL << bit_index; + + if (enabled == PIN_IRQ_ENABLE) + { + ret = s100_gpio_config_irq(pin, s100_pin_irq_hdr[pin].mode); + if (ret != RT_EOK) + { + return ret; + } + + gpio->intmask &= ~bit; + gpio->inten |= bit; + } + else if (enabled == PIN_IRQ_DISABLE) + { + gpio->intmask |= bit; + gpio->inten &= ~bit; + gpio->porta_eoi = bit; + } + else + { + return -RT_EINVAL; + } + + return RT_EOK; +} + +static const struct rt_pin_ops s100_pin_ops = +{ + s100_pin_mode, + s100_pin_write_device, + s100_pin_read_device, + s100_pin_attach_irq, + s100_pin_detach_irq, + s100_pin_irq_enable, + RT_NULL, +}; + +static void s100_gpio_irq_dispatch(rt_uint8_t port_index) +{ + rt_uint32_t status; + rt_uint8_t bit; + s100_gpio_reg_t *gpio; + + gpio = s100_gpio_ports[port_index]; + status = gpio->intstatus; + gpio->porta_eoi = status; + + for (bit = 0; bit < S100_GPIO_CHANNELS_PER_PORT; bit++) + { + s100_pin_t pin; + rt_uint32_t mask = 1UL << bit; + + if ((status & mask) == 0U) + { + continue; + } + + if (s100_gpio_to_pin(port_index, bit, &pin) != RT_EOK) + { + continue; + } + + if (s100_pin_irq_hdr[pin].hdr != RT_NULL) + { + s100_pin_irq_hdr[pin].hdr(s100_pin_irq_hdr[pin].args); + } + } +} + +static void s100_gpio_irq0_isr(int vector, void *param) +{ + RT_UNUSED(vector); + RT_UNUSED(param); + s100_gpio_irq_dispatch(0); +} + +static void s100_gpio_irq1_isr(int vector, void *param) +{ + RT_UNUSED(vector); + RT_UNUSED(param); + s100_gpio_irq_dispatch(1); +} + +static void s100_gpio_irq2_isr(int vector, void *param) +{ + RT_UNUSED(vector); + RT_UNUSED(param); + s100_gpio_irq_dispatch(2); +} + +int rt_hw_pin_init(void) +{ + rt_size_t i; + rt_isr_handler_t handlers[S100_GPIO_PORT_COUNT] = + { + s100_gpio_irq0_isr, + s100_gpio_irq1_isr, + s100_gpio_irq2_isr, + }; + + for (i = 0; i < S100_GPIO_PIN_COUNT; i++) + { + s100_pin_irq_hdr[i].pin = -1; + s100_pin_irq_hdr[i].mode = 0; + s100_pin_irq_hdr[i].hdr = RT_NULL; + s100_pin_irq_hdr[i].args = RT_NULL; + } + + /* + * Each GPIO block reports through one parent interrupt. The per-pin RT- + * Thread callbacks are dispatched in s100_gpio_irq_dispatch() after the + * block-level status register is decoded. + */ + for (i = 0; i < S100_GPIO_PORT_COUNT; i++) + { + rt_hw_interrupt_install(s100_gpio_port_irqs[i], handlers[i], RT_NULL, "gpio"); + rt_hw_interrupt_set_triger_mode(s100_gpio_port_irqs[i], IRQ_MODE_TRIG_LEVEL); + rt_hw_interrupt_umask(s100_gpio_port_irqs[i]); + } + + return rt_device_pin_register("pin", &s100_pin_ops, RT_NULL); +} +INIT_DEVICE_EXPORT(rt_hw_pin_init); diff --git a/bsp/rdk/s100/drivers/drv_gpio.h b/bsp/rdk/s100/drivers/drv_gpio.h new file mode 100644 index 00000000000..e60900dacdd --- /dev/null +++ b/bsp/rdk/s100/drivers/drv_gpio.h @@ -0,0 +1,30 @@ +#ifndef DRV_GPIO_H__ +#define DRV_GPIO_H__ + +#include "drv_pinmux.h" + +/* + * MCU GPIO access layer used by both the RT-Thread pin device and simple + * board-level helpers. + */ +typedef enum +{ + S100_PIN_DIR_IN = 0, + S100_PIN_DIR_OUT, + S100_PIN_DIR_HIGH_Z, +} s100_pin_direction_t; + +typedef enum +{ + S100_PIN_LEVEL_LOW = 0, + S100_PIN_LEVEL_HIGH, +} s100_pin_level_t; + +rt_err_t s100_gpio_set_direction(s100_pin_t pin, s100_pin_direction_t direction); +rt_err_t s100_gpio_write_pin(s100_pin_t pin, s100_pin_level_t level); +rt_err_t s100_gpio_read_pin(s100_pin_t pin, s100_pin_level_t *level); + +void s100_gpio_write(rt_uint8_t pin, rt_uint8_t value); +rt_uint8_t s100_gpio_read(rt_uint8_t pin); + +#endif diff --git a/bsp/rdk/s100/drivers/drv_pinmux.c b/bsp/rdk/s100/drivers/drv_pinmux.c new file mode 100644 index 00000000000..70916629a7d --- /dev/null +++ b/bsp/rdk/s100/drivers/drv_pinmux.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ + +#include "drv_pinmux.h" + +#define S100_PIN_MUX_REG_BASE 0x234C0060U +#define S100_PIN_CONFIG_REG_BASE 0x234D0010U + +#define S100_PORT_IP_NUM 2 +#define S100_PORT_LLD_IP_NUM 6 +#define S100_PORT_PIN_NUM (uint8_t)124U +#define S100_PORT_MCU_PIN_NUM (uint8_t)88U +#define S100_PORT_AON_PIN_NUM (uint8_t)18U + +#define AON_PIN_NUM(aon_gpio_idx) ((aon_gpio_idx) + (S100_PORT_MCU_PIN_NUM)) +/* + * Keep the same MCU GPIO blacklist as the SDK Port subsystem. + * These pins are reserved for power/debug or other board-critical uses + * and must not be reconfigured as generic GPIO from RT-Thread. + * + * Note: + * The SDK also blacklists a few AON pins. The current cpu1_rtthread BSP + * driver only manages MCU GPIO pins, so only the MCU-side blacklist is + * enforced here. + */ +static const s100_pin_t s100_gpio_blacklist[] = +{ + 0, /* S100 Power related pins */ + 5, /* S100 debug uart tx */ + 38, /* S100 Power related pins */ + 15, /* S100 Power related pins */ + 68, /* S100 Power related pins */ + 69, /* S100 Power related pins */ + 71, /* S100 Power related pins */ + 80, /* S100 Power related pins */ + 81, /* S100 Power related pins */ + 82, /* S100 Power related pins */ + 83, /* S100 Power related pins */ + AON_PIN_NUM(0), /* S100 debug uart rx */ + AON_PIN_NUM(12), /* S100 Power related pins */ +}; + +typedef struct +{ + volatile rt_uint32_t reg_pin_mux_func; +} s100_pin_mux_reg_t; + +typedef union +{ + struct + { + volatile rt_uint32_t ds : 4; + volatile rt_uint32_t ie : 1; + volatile rt_uint32_t pd : 1; + volatile rt_uint32_t pu : 1; + volatile rt_uint32_t st : 1; + volatile rt_uint32_t rsvd: 24; + } type0; + volatile rt_uint32_t value; +} s100_pin_cfg_reg_t; + +static s100_pin_mux_reg_t *const s100_pin_mux_regs = + (s100_pin_mux_reg_t *)S100_PIN_MUX_REG_BASE; +static s100_pin_cfg_reg_t *const s100_pin_cfg_regs = + (s100_pin_cfg_reg_t *)S100_PIN_CONFIG_REG_BASE; + +static rt_bool_t s100_pin_is_blacklisted(s100_pin_t pin) +{ + rt_size_t i; + + for (i = 0; i < sizeof(s100_gpio_blacklist) / sizeof(s100_gpio_blacklist[0]); i++) + { + if (pin == s100_gpio_blacklist[i]) + { + return RT_TRUE; + } + } + + return RT_FALSE; +} + +rt_bool_t s100_pin_is_valid(s100_pin_t pin) +{ + if (pin >= S100_GPIO_PIN_COUNT) + { + return RT_FALSE; + } + + /* Pin 79 is a hole in the MCU GPIO numbering and must be skipped. */ + if (pin == 79U) + { + return RT_FALSE; + } + + if (s100_pin_is_blacklisted(pin) == RT_TRUE) + { + return RT_FALSE; + } + + return RT_TRUE; +} + +rt_err_t s100_pin_set_function(s100_pin_t pin, s100_pin_function_t function) +{ + if (!s100_pin_is_valid(pin)) + { + return -RT_EINVAL; + } + + s100_pin_mux_regs[pin].reg_pin_mux_func = (rt_uint32_t)function & 0x3U; + return RT_EOK; +} + +rt_err_t s100_pin_set_pull(s100_pin_t pin, s100_pin_pull_t pull) +{ + s100_pin_cfg_reg_t cfg; + + if (!s100_pin_is_valid(pin)) + { + return -RT_EINVAL; + } + + cfg = s100_pin_cfg_regs[pin]; + cfg.type0.ie = 1U; + cfg.type0.st = 1U; + cfg.type0.pu = 0U; + cfg.type0.pd = 0U; + + if (pull == S100_PIN_PULL_UP) + { + cfg.type0.pu = 1U; + } + else if (pull == S100_PIN_PULL_DOWN) + { + cfg.type0.pd = 1U; + } + + s100_pin_cfg_regs[pin].value = cfg.value; + return RT_EOK; +} diff --git a/bsp/rdk/s100/drivers/drv_pinmux.h b/bsp/rdk/s100/drivers/drv_pinmux.h new file mode 100644 index 00000000000..b1369193f3e --- /dev/null +++ b/bsp/rdk/s100/drivers/drv_pinmux.h @@ -0,0 +1,37 @@ +#ifndef DRV_PINMUX_H__ +#define DRV_PINMUX_H__ + +#include + +/* + * Shared S100 pinctrl helpers. + * + * GPIO, UART, SPI and other MCU-side drivers can reuse this layer to switch + * mux function and electrical attributes without duplicating pin register + * knowledge in every peripheral driver. + */ +typedef rt_uint8_t s100_pin_t; + +typedef enum +{ + S100_PIN_PULL_NONE = 0, + S100_PIN_PULL_DOWN, + S100_PIN_PULL_UP, +} s100_pin_pull_t; + +typedef enum +{ + S100_PIN_FUNC0 = 0, + S100_PIN_FUNC1, + S100_PIN_FUNC2, + S100_PIN_FUNC_GPIO, +} s100_pin_function_t; + +#define S100_GPIO_PIN_COUNT 88U + +/* Returns RT_FALSE for reserved/unsupported pins, including the SDK blacklist. */ +rt_bool_t s100_pin_is_valid(s100_pin_t pin); +rt_err_t s100_pin_set_function(s100_pin_t pin, s100_pin_function_t function); +rt_err_t s100_pin_set_pull(s100_pin_t pin, s100_pin_pull_t pull); + +#endif diff --git a/bsp/rdk/s100/drivers/drv_timer.c b/bsp/rdk/s100/drivers/drv_timer.c new file mode 100644 index 00000000000..90572fa77ed --- /dev/null +++ b/bsp/rdk/s100/drivers/drv_timer.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ + +#include +#include +#include + +#include "board.h" + +#define S100_SYSCNT_BASE 0x23110000U +#define S100_SYSCNT_CTRL_OSCON_MASK (0x1U) +#define S100_SYSCNT_CLK_HZ (40000000U) +#define S100_GENERIC_TIMER_PPI 30 + +#define CNTP_CTL_ENABLE (1U << 0) + +struct s100_syscnt +{ + volatile rt_uint32_t ctrl; + volatile rt_uint32_t stat; + volatile rt_uint32_t cntcvl; + volatile rt_uint32_t cntcvu; + rt_uint8_t reserved[16]; + volatile rt_uint32_t cntfid0; +}; + +static volatile struct s100_syscnt *const s100_syscnt = + (volatile struct s100_syscnt *)S100_SYSCNT_BASE; + +static rt_uint32_t s100_tick_interval; +static rt_uint64_t s100_read_cntpct(void) +{ + rt_uint32_t low; + rt_uint32_t high; + + __asm volatile ("mrrc p15, 0, %0, %1, c14" : "=r"(low), "=r"(high)); + + return (((rt_uint64_t)high) << 32) | low; +} + +static void s100_write_cntp_cval(rt_uint64_t value) +{ + rt_uint32_t low = (rt_uint32_t)value; + rt_uint32_t high = (rt_uint32_t)(value >> 32); + + __asm volatile ("mcrr p15, 2, %0, %1, c14" :: "r"(low), "r"(high)); +} + +static void s100_write_cntp_ctl(rt_uint32_t value) +{ + __asm volatile ("mcr p15, 0, %0, c14, c2, 1" :: "r"(value)); +} + +static void s100_program_next_tick(rt_uint32_t delta) +{ + s100_write_cntp_cval(s100_read_cntpct() + delta); +} + +static void rt_hw_timer_isr(int vector, void *param) +{ + RT_UNUSED(vector); + RT_UNUSED(param); + + s100_program_next_tick(s100_tick_interval); + rt_tick_increase(); +} + +int rt_hw_timer_init(void) +{ + s100_tick_interval = S100_SYSCNT_CLK_HZ / RT_TICK_PER_SECOND; + RT_ASSERT(s100_tick_interval > 0U); + + s100_syscnt->cntfid0 = S100_SYSCNT_CLK_HZ; + s100_syscnt->ctrl |= S100_SYSCNT_CTRL_OSCON_MASK; + + s100_write_cntp_ctl(0U); + s100_program_next_tick(s100_tick_interval); + s100_write_cntp_ctl(CNTP_CTL_ENABLE); + + rt_hw_interrupt_install(S100_GENERIC_TIMER_PPI, rt_hw_timer_isr, RT_NULL, "tick"); + rt_hw_interrupt_umask(S100_GENERIC_TIMER_PPI); + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_timer_init); diff --git a/bsp/rdk/s100/drivers/drv_uart_v2.c b/bsp/rdk/s100/drivers/drv_uart_v2.c new file mode 100644 index 00000000000..50d236889af --- /dev/null +++ b/bsp/rdk/s100/drivers/drv_uart_v2.c @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ + + +#include +#include +#include "interrupt.h" + +#ifdef RT_USING_SERIAL_V2 + +#define UART_MAX_COUNT (3u) +#define UART_SYS_CLK (200000000u) +#define UART_CONFIG_TIMEOUT (0xffu) +#define UART_FCR_DEFVAL (UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR) + +#define SYS_REG_UART_CTRL ((volatile rt_uint32_t *)0x23660084u) + +#define UART_4_BASE (0x23400000u) +#define UART_5_BASE (0x23410000u) +#define UART_6_BASE (0x23420000u) + +#define UART_CTRL_UART4_RX_IN_MASK (0x00000001u) +#define UART_CTRL_UART5_RX_IN_MASK (0x00000010u) +#define UART_CTRL_UART6_RX_IN_MASK (0x00000100u) + +#define UART_FCR_FIFO_DIS (0x00u) +#define UART_FCR_FIFO_EN (0x01u) +#define UART_FCR_CLEAR_RCVR (0x02u) +#define UART_FCR_CLEAR_XMIT (0x04u) +#define UART_FCR_RXSR (0x02u) +#define UART_FCR_TXSR (0x04u) +#define UART_FCR_RX_TRIGGER_MASK (0xC0u) +#define UART_FCR_RX_TRIGGER_8 (0x80u) + +#define UART_LCR_WLS_MSK (0x03u) +#define UART_LCR_WLS_BASE (5u) +#define UART_LCR_STB (0x04u) +#define UART_LCR_PEN (0x08u) +#define UART_LCR_EPS (0x10u) +#define UART_LCR_DLAB (0x80u) + +#define UART_LSR_DR (0x01u) +#define UART_LSR_THRE (0x20u) + +#define UART_IIR_NO_INT (0x01u) +#define UART_IIR_ID (0x0eu) +#define UART_IIR_THRI (0x02u) +#define UART_IIR_RDI (0x04u) +#define UART_IIR_RLSI (0x06u) +#define UART_IIR_BUSY_DETECT (0x07u) +#define UART_IIR_CHAR_TIMEOUT (0x0cu) + +/* + * These are the definitions for the Interrupt Enable Register + */ +#define UART_IER_MSI (0x08U) /**< Enable Modem status interrupt */ +#define UART_IER_RLSI (0x04U) /**< Enable receiver line status interrupt */ +#define UART_IER_THRI (0x02U) /**< Enable Transmitter holding register int. */ +#define UART_IER_RDI (0x01U) /**< Enable receiver data interrupt */ + +#define UART4_IRQn (45) +#define UART5_IRQn (46) +#define UART6_IRQn (47) + +#define UART_USR_BUSY (0x01u) +#define UART_USR_TFNF (0x02u) +#define UART_USR_RFNE (0x08u) + +typedef struct +{ + volatile rt_uint32_t RBR; + volatile rt_uint32_t IER; + volatile rt_uint32_t FCR; + volatile rt_uint32_t LCR; + volatile rt_uint32_t MCR; + volatile rt_uint32_t LSR; + volatile rt_uint32_t MSR; + volatile rt_uint32_t RESERVED1[21]; + volatile rt_uint32_t FAR; + volatile rt_uint32_t TFR; + volatile rt_uint32_t RFW; + volatile rt_uint32_t USR; + volatile rt_uint32_t TFL; + volatile rt_uint32_t RFL; + volatile rt_uint32_t RESERVED2[7]; + volatile rt_uint32_t HTX; + volatile rt_uint32_t DMASA; + volatile rt_uint32_t RESERVED3[5]; + volatile rt_uint32_t DLF; +} s100_uart_reg_t; + +struct s100_uart +{ + struct rt_serial_device serial; + s100_uart_reg_t *regs; + rt_uint32_t rx_mask; + int irqno; + rt_uint16_t rx_bufsz; + rt_uint16_t tx_bufsz; + rt_uint32_t fcr_shadow; + const char *name; +}; + +#if defined(BSP_USING_UART4) +#define S100_UART4_DESC \ + { \ + .regs = (s100_uart_reg_t *)UART_4_BASE, \ + .rx_mask = UART_CTRL_UART4_RX_IN_MASK, \ + .irqno = UART4_IRQn, \ + .rx_bufsz = BSP_UART4_RX_BUFSIZE, \ + .tx_bufsz = BSP_UART4_TX_BUFSIZE, \ + .name = "uart4", \ + } +#endif + +#if defined(BSP_USING_UART5) +#define S100_UART5_DESC \ + { \ + .regs = (s100_uart_reg_t *)UART_5_BASE, \ + .rx_mask = UART_CTRL_UART5_RX_IN_MASK, \ + .irqno = UART5_IRQn, \ + .rx_bufsz = BSP_UART5_RX_BUFSIZE, \ + .tx_bufsz = BSP_UART5_TX_BUFSIZE, \ + .name = "uart5", \ + } +#endif + +#if defined(BSP_USING_UART6) +#define S100_UART6_DESC \ + { \ + .regs = (s100_uart_reg_t *)UART_6_BASE, \ + .rx_mask = UART_CTRL_UART6_RX_IN_MASK, \ + .irqno = UART6_IRQn, \ + .rx_bufsz = BSP_UART6_RX_BUFSIZE, \ + .tx_bufsz = BSP_UART6_TX_BUFSIZE, \ + .name = "uart6", \ + } +#endif + +static struct s100_uart s100_uarts[] = +{ +#if defined(BSP_USING_UART4) + S100_UART4_DESC, +#endif + +#if defined(BSP_USING_UART5) + S100_UART5_DESC, +#endif + +#if defined(BSP_USING_UART6) + S100_UART6_DESC, +#endif + +}; + +static void s100_uart_config_default(struct s100_uart *uart) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + config.baud_rate = BAUD_RATE_921600; + config.rx_bufsz = uart->rx_bufsz; + config.tx_bufsz = uart->tx_bufsz; + + uart->serial.config = config; +} + + +static void s100_uart_rx_drain(struct s100_uart *uart) +{ + rt_bool_t rx_indicated = RT_FALSE; + + while ((uart->regs->USR & UART_USR_RFNE) != 0u) + { + rt_uint8_t ch = (rt_uint8_t)(uart->regs->RBR & 0xffu); + + if (uart->serial.serial_rx != RT_NULL) + { + rt_hw_serial_control_isr(&uart->serial, RT_HW_SERIAL_CTRL_PUTC, &ch); + rx_indicated = RT_TRUE; + } + } + + if (rx_indicated != RT_FALSE) + { + rt_hw_serial_isr(&uart->serial, RT_SERIAL_EVENT_RX_IND); + } +} + +static void s100_uart_isr(int vector, void *param) +{ + struct s100_uart *uart = (struct s100_uart *)param; + rt_uint32_t iir; + + RT_UNUSED(vector); + + /* IIR shares the FCR offset; read it with IIR semantics here. */ + iir = *((volatile rt_uint32_t *)&uart->regs->FCR) & 0x0fu; + if ((iir & UART_IIR_NO_INT) != 0u) + { + return; + } + switch (iir & UART_IIR_ID) + { + case UART_IIR_RDI: + case UART_IIR_CHAR_TIMEOUT: + s100_uart_rx_drain(uart); + break; + case UART_IIR_RLSI: + /* Reading LSR clears line status sources, then drain any pending data. */ + (void)uart->regs->LSR; + s100_uart_rx_drain(uart); + break; + case UART_IIR_BUSY_DETECT: + (void)uart->regs->USR; + break; + case UART_IIR_THRI: + default: + break; + } +} + +static void s100_uart_clear_irq(struct s100_uart *uart) +{ + uart->regs->IER &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_THRI | UART_IER_MSI); +} + +static void s100_uart_fcr_write(struct s100_uart *uart, rt_uint32_t val) +{ + uart->fcr_shadow = val; + uart->regs->FCR = uart->fcr_shadow; +} + +static void s100_uart_set_rx_trigger(struct s100_uart *uart, rt_uint32_t trigger) +{ + uart->fcr_shadow &= ~UART_FCR_CLEAR_RCVR; + uart->fcr_shadow &= ~UART_FCR_CLEAR_XMIT; + uart->fcr_shadow &= ~UART_FCR_RX_TRIGGER_MASK; + uart->fcr_shadow |= trigger; + uart->regs->FCR = uart->fcr_shadow; +} + +static rt_err_t s100_uart_config_prepare(struct s100_uart *uart) +{ + rt_uint32_t timeout = UART_CONFIG_TIMEOUT; + + while (((uart->regs->USR & UART_USR_BUSY) != 0u) && (timeout != 0u)) + { + s100_uart_fcr_write(uart, UART_FCR_FIFO_DIS); + s100_uart_fcr_write(uart, UART_FCR_CLEAR_RCVR); + s100_uart_fcr_write(uart, UART_FCR_CLEAR_XMIT); + timeout--; + } + + return (timeout != 0u) ? RT_EOK : -RT_ETIMEOUT; +} + +static void s100_uart_set_baud(struct s100_uart *uart, rt_uint32_t baud_rate) +{ + rt_uint32_t baud_div_x64; + rt_uint32_t baud_div_int; + rt_uint32_t baud_div_fraction; + + baud_div_x64 = (UART_SYS_CLK * 4u) / baud_rate; + baud_div_int = baud_div_x64 / 64u; + if (baud_div_int == 0u) + { + baud_div_int = 1u; + } + baud_div_fraction = baud_div_x64 - (baud_div_int * 64u); + + uart->regs->LCR |= UART_LCR_DLAB; + uart->regs->DLF = baud_div_fraction; + uart->regs->RBR = baud_div_int & 0xffu; + uart->regs->LCR &= ~UART_LCR_DLAB; +} + +static rt_err_t s100_uart_set_lcr(struct s100_uart *uart, struct serial_configure *cfg) +{ + rt_uint32_t lcr = 0; + + switch (cfg->data_bits) + { + case DATA_BITS_5: + case DATA_BITS_6: + case DATA_BITS_7: + case DATA_BITS_8: + lcr |= (cfg->data_bits - UART_LCR_WLS_BASE) & UART_LCR_WLS_MSK; + break; + default: + return -RT_EINVAL; + } + + switch (cfg->stop_bits) + { + case STOP_BITS_1: + break; + case STOP_BITS_2: + lcr |= UART_LCR_STB; + break; + default: + return -RT_EINVAL; + } + + switch (cfg->parity) + { + case PARITY_NONE: + break; + case PARITY_ODD: + lcr |= UART_LCR_PEN; + break; + case PARITY_EVEN: + lcr |= UART_LCR_PEN | UART_LCR_EPS; + break; + default: + return -RT_EINVAL; + } + + uart->regs->LCR &= ~(UART_LCR_WLS_MSK | UART_LCR_STB | UART_LCR_PEN | UART_LCR_EPS); + uart->regs->LCR |= lcr; + + return RT_EOK; +} + +static void s100_uart_set_fifo(struct s100_uart *uart) +{ + s100_uart_clear_irq(uart); + s100_uart_fcr_write(uart, UART_FCR_DEFVAL); + s100_uart_set_rx_trigger(uart, UART_FCR_RX_TRIGGER_8); +} + +static rt_err_t s100_uart_configure(struct rt_serial_device *serial, + struct serial_configure *cfg) +{ + + + struct s100_uart *uart; + rt_err_t ret; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + if ((cfg->baud_rate == 0u) || (cfg->flowcontrol != RT_SERIAL_FLOWCONTROL_NONE)) + { + return -RT_EINVAL; + } + + uart = (struct s100_uart *)serial->parent.user_data; + + (*(uint32_t *)SYS_REG_UART_CTRL) |= uart->rx_mask; + uart->regs->MCR = 0u; + + ret = s100_uart_config_prepare(uart); + if (ret == RT_EOK) + { + s100_uart_set_baud(uart, cfg->baud_rate); + ret = s100_uart_set_lcr(uart, cfg); + s100_uart_set_fifo(uart); + } + + (*(uint32_t *)SYS_REG_UART_CTRL) &= ~uart->rx_mask; + + return ret; +} + +static rt_err_t s100_uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct s100_uart *uart; + rt_ubase_t ctrl_arg = (rt_ubase_t) arg; + + RT_ASSERT(serial != RT_NULL); + + uart = (struct s100_uart *)serial->parent.user_data; + + if(ctrl_arg & (RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING)) + { + ctrl_arg = RT_DEVICE_FLAG_INT_RX; + } + else if(ctrl_arg & (RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING)) + { + ctrl_arg = RT_DEVICE_FLAG_INT_TX; + } + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) + { + /* disable rx irq */ + uart->regs->IER &= ~(UART_IER_RDI | UART_IER_RLSI); + } + else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX) + { + /* disable tx irq */ + uart->regs->IER &= (~UART_IER_THRI); + } + break; + + case RT_DEVICE_CTRL_SET_INT: + if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) + { + /* enable rx irq */ + uart->regs->IER |= (UART_IER_RDI | UART_IER_RLSI); + rt_hw_interrupt_umask(uart->irqno); + + } else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX) + { + /* enable tx irq */ + uart->regs->IER |= UART_IER_THRI; + rt_hw_interrupt_umask(uart->irqno); + } + + break; + case RT_DEVICE_CTRL_CONFIG: + return s100_uart_control(serial, RT_DEVICE_CTRL_SET_INT, (void *)ctrl_arg); + case RT_DEVICE_CTRL_CLOSE: + uart->regs->IER &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_THRI | UART_IER_MSI); + rt_hw_interrupt_mask(uart->irqno); + break; + default: + break; + } + return RT_EOK; +} + +static int s100_uart_putc(struct rt_serial_device *serial, char c) +{ + + struct s100_uart *uart; + + RT_ASSERT(serial != RT_NULL); + + uart = (struct s100_uart *)serial->parent.user_data; + + while ((uart->regs->LSR & UART_LSR_THRE) == 0u) + { + } + + uart->regs->RBR = (rt_uint8_t)c; + return 1; +} + +static int s100_uart_getc(struct rt_serial_device *serial) +{ + struct s100_uart *uart; + + RT_ASSERT(serial != RT_NULL); + + uart = (struct s100_uart *)serial->parent.user_data; + + if ((uart->regs->USR & UART_USR_RFNE) == 0u) + { + return -1; + } + + return (int)(uart->regs->RBR & 0xffu); +} + +static rt_ssize_t s100_uart_transmit(struct rt_serial_device *serial, + rt_uint8_t *buf, + rt_size_t size, + rt_uint32_t tx_flag) +{ + rt_size_t i; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(buf != RT_NULL); + RT_UNUSED(tx_flag); + + for (i = 0; i < size; i++) + { + while ((((struct s100_uart *)serial->parent.user_data)->regs->USR & UART_USR_TFNF) == 0u) + { + } + s100_uart_putc(serial, (char)buf[i]); + } + + return size; +} + +static const struct rt_uart_ops s100_uart_ops = +{ + .configure = s100_uart_configure, + .control = s100_uart_control, + .putc = s100_uart_putc, + .getc = s100_uart_getc, + .transmit = s100_uart_transmit, +}; + +int rt_hw_uart_init(void) +{ + rt_err_t ret = RT_EOK; + rt_size_t i; + + for(i = 0; i < sizeof(s100_uarts) / sizeof(s100_uarts[0]); i++) + { + s100_uarts[i].serial.ops = &s100_uart_ops; + s100_uart_config_default(&s100_uarts[i]); + s100_uarts[i].serial.parent.user_data = &s100_uarts[i]; + + ret = rt_hw_serial_register(&s100_uarts[i].serial, + s100_uarts[i].name, + RT_DEVICE_FLAG_RDWR, + (void*)&s100_uarts[i]); + if (ret != RT_EOK) + { + return ret; + } + + rt_hw_interrupt_install(s100_uarts[i].irqno,s100_uart_isr, &s100_uarts[i], s100_uarts[i].name); + } + + return ret; +} +INIT_BOARD_EXPORT(rt_hw_uart_init); +#endif /* RT_USING_SERIAL_V2 */ diff --git a/bsp/rdk/s100/link.lds b/bsp/rdk/s100/link.lds new file mode 100644 index 00000000000..e9c7daaabf8 --- /dev/null +++ b/bsp/rdk/s100/link.lds @@ -0,0 +1,233 @@ +/* + * S100 MCU1 linker script for RT-Thread on Cortex-R52. + * + * This keeps the current MCU1 memory layout from the FreeRTOS image and + * adds the symbols/sections RT-Thread's Cortex-R52 GCC port expects. + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(EL2_core_exceptions_table) + +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0000C000; +STACK_SIZE_EXC = DEFINED(__stack_size_exc__) ? __stack_size_exc__ : 0x0000C000; + +MEMORY +{ + FLASH_STARTUP (rx) : ORIGIN = 0x0CAB0000, LENGTH = 4K + FLASH (rwx) : ORIGIN = 0x0CAB1000, LENGTH = 2154K + RTOS_HEAP (rw) : ORIGIN = 0x0CCCB000, LENGTH = 512K + CAN_Reserved (rw) : ORIGIN = 0x0CD4B000, LENGTH = 64K + LOG_SHARE_Reserved (rw) : ORIGIN = 0x0CD5B000, LENGTH = 8K + SCMI_IPC_Reserved (rw) : ORIGIN = 0x0CD5D000, LENGTH = 12K + ATCM_Reserved (rwx) : ORIGIN = 0x0A000000, LENGTH = 64K +} + +SECTIONS +{ + .startup : + { + . = ALIGN(32); + __startup_start = .; + KEEP(*(.EL2_core_exceptions_table)) + + . = ALIGN(32); + KEEP(*(.EL1_core_exceptions_table)) + + . = ALIGN(32); + KEEP(*(.EL2_Reset_Handler)) + + . = ALIGN(4); + KEEP(*(.text.entrypoint)) + KEEP(*(.vectors)) + + . = ALIGN(32); + __startup_end = .; + } > FLASH_STARTUP + + .text : + { + PROVIDE(__text_start = .); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.glue_7) + *(.glue_7t) + + /* section information for utest */ + . = ALIGN(8); + PROVIDE(__rt_utest_tc_tab_start = .); + KEEP(*(UtestTcTab)) + PROVIDE(__rt_utest_tc_tab_end = .); + + /* section information for finsh shell */ + . = ALIGN(8); + PROVIDE(__fsymtab_start = .); + KEEP(*(FSymTab)) + PROVIDE(__fsymtab_end = .); + . = ALIGN(8); + PROVIDE(__vsymtab_start = .); + KEEP(*(VSymTab)) + PROVIDE(__vsymtab_end = .); + . = ALIGN(8); + + /* section information for modules */ + . = ALIGN(8); + PROVIDE(__rtmsymtab_start = .); + KEEP(*(RTMSymTab)) + PROVIDE(__rtmsymtab_end = .); + + /* section information for initialization */ + . = ALIGN(8); + PROVIDE(__rt_init_start = .); + KEEP(*(SORT(.rti_fn*))) + PROVIDE(__rt_init_end = .); + + /* section information for usb usbh_class_info */ + . = ALIGN(4); + __usbh_class_info_start__ = .; + KEEP(*(.usbh_class_info)) + . = ALIGN(4); + __usbh_class_info_end__ = .; + + PROVIDE(__text_end = .); + } > FLASH + + .resource_table : + { + . = ALIGN(8); + __resource_table_start = .; + KEEP(*(.resource_table)) + KEEP(*(.resource_table.*)) + . = ALIGN(8); + __resource_table_end = .; + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .const : + { + . = ALIGN(32); + *(.const) + *(.rodata .rodata.*) + } > FLASH + + .data : + { + . = ALIGN(64); + __image_rw_start__ = .; + __data_start__ = .; /* Create a global symbol at data start. */ + *(.data .data.*) /* .data sections */ + . = ALIGN(64); + __data_end__ = .; /* Define a global symbol at data end. */ + } > FLASH + + .bss (NOLOAD): + { + /* + * We need some free space to page or cpu stack, move .bss.noclean.* + * to optimize size. + */ + . = ALIGN(16); + PROVIDE(__bss_noclean_start = .); + *(.bss.noclean.*) + PROVIDE(__bss_noclean_end = .); + . = ALIGN(8); + PROVIDE(__bss_start = .); + *(.bss) + *(.bss.*) + *(.dynbss) + *(COMMON) + . = ALIGN(8); + PROVIDE(__bss_end = .); + } > FLASH + + .stack (NOLOAD) : + { + . = ALIGN(64); + __STACK_START = .; + __StackLimit = .; + __stack_start__ = .; + . += STACK_SIZE; + __stack_end__ = .; + __StackTop = .; + } > FLASH + + .stack_exc (NOLOAD) : + { + . = ALIGN(64); + __StackLimit_exc = .; + __stack_start_exc__ = .; + . += STACK_SIZE_EXC; + __stack_end_exc__ = .; + __StackTop_exc = .; + . = ALIGN(64); + __image_rw_end__ = .; + } > FLASH + + _end = .; + /*-------- LABELS USED IN CODE -------------------------------*/ + SRAM_START_ADDR = ORIGIN(FLASH_STARTUP); + FLASH_STARTUP_LEN = LENGTH(FLASH_STARTUP); + FLASH_SEC_ADDR = ORIGIN(FLASH); + MCU_LOG_START_ADDR = ORIGIN(LOG_SHARE_Reserved); + MCU_LOG_SIZE = LENGTH(LOG_SHARE_Reserved); + __SCMI_IPC_START_ADDR = ORIGIN(SCMI_IPC_Reserved); + __SCMI_IPC_SIZE = LENGTH(SCMI_IPC_Reserved); + NON_SECURE_START_ADDR = ORIGIN(LOG_SHARE_Reserved); + CAN_START_ADDR = ORIGIN(CAN_Reserved); + ATCM_START_ADDR = ORIGIN(ATCM_Reserved); + ATCM_SIZE = LENGTH(ATCM_Reserved); + OS_HEAP_START_ADDR = ORIGIN(RTOS_HEAP); + OS_HEAP_END_ADDR = ORIGIN(RTOS_HEAP) + LENGTH(RTOS_HEAP); + OS_HEAP_SIZE = LENGTH(RTOS_HEAP); + + /* Keep __image_rw_end__ ~ OS_HEAP_START_ADDR unmapped as a guard gap. */ + + PROVIDE(SRAM_SIZE = 0x34FFFF); + PROVIDE(MCU0_LOG_START_ADDR = 0x0CAAB000); /* Base addr from MCU0 link region "LOG_SHARE_Reserved" */ + PROVIDE(MCU_STATE_START_ADDR = 0x0C800800);/* Base addr from MCU0 link region "MCU_STATE_Reserved" */ + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/rdk/s100/rtconfig.h b/bsp/rdk/s100/rtconfig.h new file mode 100644 index 00000000000..0cebd660dcc --- /dev/null +++ b/bsp/rdk/s100/rtconfig.h @@ -0,0 +1,428 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +#define SOC_S100 + +/* S100 BSP Options */ + +#define RT_USING_FPU +/* end of S100 BSP Options */ + +/* RT-Thread Kernel */ + +/* klibc options */ + +/* rt_vsnprintf options */ + +/* end of rt_vsnprintf options */ + +/* rt_vsscanf options */ + +/* end of rt_vsscanf options */ + +/* rt_memset options */ + +/* end of rt_memset options */ + +/* rt_memcpy options */ + +/* end of rt_memcpy options */ + +/* rt_memmove options */ + +/* end of rt_memmove options */ + +/* rt_memcmp options */ + +/* end of rt_memcmp options */ + +/* rt_strstr options */ + +/* end of rt_strstr options */ + +/* rt_strcasecmp options */ + +/* end of rt_strcasecmp options */ + +/* rt_strncpy options */ + +/* end of rt_strncpy options */ + +/* rt_strcpy options */ + +/* end of rt_strcpy options */ + +/* rt_strncmp options */ + +/* end of rt_strncmp options */ + +/* rt_strcmp options */ + +/* end of rt_strcmp options */ + +/* rt_strlen options */ + +/* end of rt_strlen options */ + +/* rt_strnlen options */ + +/* end of rt_strnlen options */ +/* end of klibc options */ +#define RT_NAME_MAX 16 +#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_OVERFLOW_CHECK +#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 + +/* kservice options */ + +/* end of kservice options */ +#define RT_USING_DEBUG +#define RT_DEBUGING_ASSERT +#define RT_DEBUGING_COLOR +#define RT_DEBUGING_CONTEXT + +/* 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_DEVICE_OPS +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 512 +#define RT_CONSOLE_DEVICE_NAME "uart4" +#define RT_USING_CONSOLE_OUTPUT_CTL +#define RT_VER_NUM 0x50300 +#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 */ + +/* end of DFS: device virtual file system */ + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V2 +#define RT_SERIAL_BUF_STRATEGY_OVERWRITE +#define RT_USING_CAN +#define RT_CANMSG_BOX_SZ 16 +#define RT_CANSND_BOX_NUM 32 +#define RT_CANSND_MSG_TIMEOUT 100 +#define RT_CAN_NB_TX_FIFO_SIZE 256 +#define RT_USING_PIN +/* end of Device Drivers */ + +/* C/C++ and POSIX layer */ + +/* ISO-ANSI C layer */ + +/* Timezone and Daylight Saving Time */ + +/* 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 */ + +/* WCH HAL & SDK Drivers */ + +/* end of WCH HAL & SDK Drivers */ + +/* AT32 HAL & SDK Drivers */ + +/* end of AT32 HAL & SDK Drivers */ + +/* HC32 DDL Drivers */ + +/* end of HC32 DDL Drivers */ + +/* NXP HAL & SDK Drivers */ + +/* end of NXP HAL & SDK Drivers */ + +/* NUVOTON Drivers */ + +/* end of NUVOTON Drivers */ + +/* GD32 Drivers */ + +/* end of GD32 Drivers */ + +/* HPMicro SDK */ + +/* end of HPMicro SDK */ + +/* FT32 HAL & SDK Drivers */ + +/* end of FT32 HAL & SDK Drivers */ +/* 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 */ + +/* Onboard Peripheral Drivers */ + +#define BSP_USING_PINMUX +#define BSP_USING_GPIO +#define BSP_USING_CAN +#define BSP_USING_CAN5 +#define BSP_USING_CAN6 +#define BSP_USING_CAN7 +#define BSP_USING_CAN8 +#define BSP_USING_CAN9 +#define BSP_USING_UART +#define BSP_USING_UART4 +#define BSP_UART4_RX_BUFSIZE 1024 +#define BSP_UART4_TX_BUFSIZE 0 +/* end of Onboard Peripheral Drivers */ + +#endif diff --git a/bsp/rdk/s100/rtconfig.py b/bsp/rdk/s100/rtconfig.py new file mode 100644 index 00000000000..2d87d7bb8a3 --- /dev/null +++ b/bsp/rdk/s100/rtconfig.py @@ -0,0 +1,83 @@ +import os +import sys + + +def _config_enabled(symbol, default=False): + config_path = os.path.join(os.path.dirname(__file__), '.config') + + try: + with open(config_path, 'r', encoding='utf-8') as cfg: + text = cfg.read() + if f'CONFIG_{symbol}=y' in text: + return True + if f'# CONFIG_{symbol} is not set' in text: + return False + return default + except OSError: + return default + +# toolchains options +ARCH='arm' +CPU='cortex-r52' +CROSS_TOOL='gcc' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') + +# cross_tool provides the cross compiler +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'/opt/toolchain/gcc-arm-none-eabi-10.3-2021.10/bin' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +# BUILD = 'debug' +BUILD = 'release' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + CXX = PREFIX + 'g++' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + NM = PREFIX + 'nm' + + if _config_enabled('RT_USING_FPU', default=True): + DEVICE = ' -mcpu=cortex-r52 -marm -mfloat-abi=hard -mfpu=vfpv3-d16 -mlittle-endian' + else: + DEVICE = ' -mcpu=cortex-r52 -marm -mfloat-abi=soft -mgeneral-regs-only -mlittle-endian' + COMMON_CFLAGS = ( + ' -fno-inline' + ' -ffunction-sections' + ' -fdata-sections' + ' -fdiagnostics-parseable-fixits' + ' -fmessage-length=0' + ' -funsigned-char' + ' -funsigned-bitfields' + ' -fno-common' + ' -fno-strict-aliasing' + ' -funwind-tables' + ' -Dgcc' + ) + + CFLAGS = DEVICE + COMMON_CFLAGS + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vector -lgcc -T link.lds' + + if BUILD == 'debug': + CFLAGS += ' -Og -ggdb3 -gdwarf-4' + AFLAGS += ' -ggdb3 -gdwarf-4' + else: + CFLAGS += ' -O2' + CXXFLAGS = CFLAGS + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' diff --git a/bsp/rdk/s100/startup/SConscript b/bsp/rdk/s100/startup/SConscript new file mode 100644 index 00000000000..fd22e5e7612 --- /dev/null +++ b/bsp/rdk/s100/startup/SConscript @@ -0,0 +1,13 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.S') +CPPPATH = [cwd] + +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rdk/s100/startup/armv8.h b/bsp/rdk/s100/startup/armv8.h new file mode 100644 index 00000000000..797223ed35e --- /dev/null +++ b/bsp/rdk/s100/startup/armv8.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __ARMV8_H__ +#define __ARMV8_H__ + +/* the exception stack without VFP registers */ +struct rt_hw_exp_stack +{ + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long sp; + unsigned long lr; + unsigned long pc; + unsigned long cpsr; +}; + +struct rt_hw_stack +{ + unsigned long cpsr; + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long lr; + unsigned long pc; +}; + +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define MONITORMODE 0x16 +#define ABORTMODE 0x17 +#define HYPMODE 0x1b +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 + +#define T_Bit (1<<5) +#define F_Bit (1<<6) +#define I_Bit (1<<7) +#define A_Bit (1<<8) +#define E_Bit (1<<9) +#define J_Bit (1<<24) + +#define PABT_EXCEPTION 0x1 +#define DABT_EXCEPTION 0x2 +#define UND_EXCEPTION 0x3 +#define SWI_EXCEPTION 0x4 +#define RESV_EXCEPTION 0xF + +void rt_hw_show_register(struct rt_hw_exp_stack *regs); + +#endif diff --git a/bsp/rdk/s100/startup/backtrace.c b/bsp/rdk/s100/startup/backtrace.c new file mode 100644 index 00000000000..85a693569d8 --- /dev/null +++ b/bsp/rdk/s100/startup/backtrace.c @@ -0,0 +1,545 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-29 Jesven the first version + */ + +#ifndef __ICCARM__ +#ifndef __CHECKER__ +#if !defined (__ARM_EABI__) +#warning Your compiler does not have EABI support. +#warning ARM unwind is known to compile only with EABI compilers. +#warning Change compiler or disable ARM_UNWIND option. +#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2) && !defined(__clang__) +#warning Your compiler is too buggy; it is known to not compile ARM unwind support. +#warning Change compiler or disable ARM_UNWIND option. +#endif +#endif /* __CHECKER__ */ + +#include +#include +#include + +#define DBG_TAG "BACKTRACE" +#define DBG_LVL DBG_INFO +#include + +#ifdef RT_USING_SMART +#include +#include +#include +#endif + +rt_inline void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame) +{ + frame->fp = frame_pointer(regs); + frame->sp = regs->ARM_sp; + frame->lr = regs->ARM_lr; + frame->pc = regs->ARM_pc; +} + +struct unwind_ctrl_block { + unsigned long vrs[16]; /* virtual register set */ + const unsigned long *insn; /* pointer to the current instructions word */ + unsigned long sp_high; /* highest value of sp allowed */ + /* + * 1 : check for stack overflow for each register pop. + * 0 : save overhead if there is plenty of stack remaining. + */ + int check_each_pop; + int entries; /* number of entries left to interpret */ + int byte; /* current byte number in the instructions word */ +}; + +enum regs +{ +#ifdef CONFIG_THUMB2_KERNEL + FP = 7, +#else + FP = 11, +#endif + SP = 13, + LR = 14, + PC = 15 +}; + +static int core_kernel_text(unsigned long addr) +{ + return 1; +} + +/* Convert a prel31 symbol to an absolute address */ +#define prel31_to_addr(ptr) \ + ({ \ + /* sign-extend to 32 bits */ \ + long offset = (((long)*(ptr)) << 1) >> 1; \ + (unsigned long)(ptr) + offset; \ + }) + +/* + * Binary search in the unwind index. The entries are + * guaranteed to be sorted in ascending order by the linker. + * + * start = first entry + * origin = first entry with positive offset (or stop if there is no such entry) + * stop - 1 = last entry + */ +static const struct unwind_idx *search_index(unsigned long addr, + const struct unwind_idx *start, + const struct unwind_idx *origin, + const struct unwind_idx *stop) +{ + unsigned long addr_prel31; + + LOG_D("%s(%08lx, %x, %x, %x)", + __func__, addr, start, origin, stop); + + /* + * only search in the section with the matching sign. This way the + * prel31 numbers can be compared as unsigned longs. + */ + if (addr < (unsigned long)start) + /* negative offsets: [start; origin) */ + stop = origin; + else + /* positive offsets: [origin; stop) */ + start = origin; + + /* prel31 for address relavive to start */ + addr_prel31 = (addr - (unsigned long)start) & 0x7fffffff; + + while (start < stop - 1) + { + const struct unwind_idx *mid = start + ((stop - start) >> 1); + + /* + * As addr_prel31 is relative to start an offset is needed to + * make it relative to mid. + */ + if (addr_prel31 - ((unsigned long)mid - (unsigned long)start) < + mid->addr_offset) + stop = mid; + else + { + /* keep addr_prel31 relative to start */ + addr_prel31 -= ((unsigned long)mid - + (unsigned long)start); + start = mid; + } + } + + if (start->addr_offset <= addr_prel31) + return start; + else + { + LOG_W("unwind: Unknown symbol address %08lx", addr); + return RT_NULL; + } +} + +static const struct unwind_idx *unwind_find_origin( + const struct unwind_idx *start, const struct unwind_idx *stop) +{ + LOG_D("%s(%x, %x)", __func__, start, stop); + while (start < stop) + { + const struct unwind_idx *mid = start + ((stop - start) >> 1); + + if (mid->addr_offset >= 0x40000000) + /* negative offset */ + start = mid + 1; + else + /* positive offset */ + stop = mid; + } + LOG_D("%s -> %x", __func__, stop); + return stop; +} + +static const struct unwind_idx *unwind_find_idx(unsigned long addr, const struct unwind_idx **origin_idx, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]) +{ + const struct unwind_idx *idx = RT_NULL; + + LOG_D("%s(%08lx)", __func__, addr); + + if (core_kernel_text(addr)) + { + if (!*origin_idx) + *origin_idx = + unwind_find_origin(exidx_start, + exidx_end); + + /* main unwind table */ + idx = search_index(addr, exidx_start, + *origin_idx, + exidx_end); + } + + LOG_D("%s: idx = %x", __func__, idx); + return idx; +} + +static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl) +{ + unsigned long ret; + + if (ctrl->entries <= 0) + { + LOG_W("unwind: Corrupt unwind table"); + return 0; + } + + ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff; + + if (ctrl->byte == 0) + { + ctrl->insn++; + ctrl->entries--; + ctrl->byte = 3; + } + else + ctrl->byte--; + + return ret; +} + +/* Before poping a register check whether it is feasible or not */ +static int unwind_pop_register(struct unwind_ctrl_block *ctrl, + unsigned long **vsp, unsigned int reg) +{ + if (ctrl->check_each_pop) + if (*vsp >= (unsigned long *)ctrl->sp_high) + return -URC_FAILURE; + + ctrl->vrs[reg] = *(*vsp)++; + return URC_OK; +} + +/* Helper functions to execute the instructions */ +static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl, + unsigned long mask) +{ + unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; + int load_sp, reg = 4; + + load_sp = mask & (1 << (13 - 4)); + while (mask) + { + if (mask & 1) + if (unwind_pop_register(ctrl, &vsp, reg)) + return -URC_FAILURE; + mask >>= 1; + reg++; + } + if (!load_sp) + ctrl->vrs[SP] = (unsigned long)vsp; + + return URC_OK; +} + +static int unwind_exec_pop_r4_to_rN(struct unwind_ctrl_block *ctrl, + unsigned long insn) +{ + unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; + int reg; + + /* pop R4-R[4+bbb] */ + for (reg = 4; reg <= 4 + (insn & 7); reg++) + if (unwind_pop_register(ctrl, &vsp, reg)) + return -URC_FAILURE; + + if (insn & 0x8) + if (unwind_pop_register(ctrl, &vsp, 14)) + return -URC_FAILURE; + + ctrl->vrs[SP] = (unsigned long)vsp; + + return URC_OK; +} + +static int unwind_exec_pop_subset_r0_to_r3(struct unwind_ctrl_block *ctrl, + unsigned long mask) +{ + unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; + int reg = 0; + + /* pop R0-R3 according to mask */ + while (mask) + { + if (mask & 1) + if (unwind_pop_register(ctrl, &vsp, reg)) + return -URC_FAILURE; + mask >>= 1; + reg++; + } + ctrl->vrs[SP] = (unsigned long)vsp; + + return URC_OK; +} + +/* + * Execute the current unwind instruction. + */ +static int unwind_exec_insn(struct unwind_ctrl_block *ctrl) +{ + unsigned long insn = unwind_get_byte(ctrl); + int ret = URC_OK; + + LOG_D("%s: insn = %08lx", __func__, insn); + + if ((insn & 0xc0) == 0x00) + ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4; + else if ((insn & 0xc0) == 0x40) + ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4; + else if ((insn & 0xf0) == 0x80) + { + unsigned long mask; + + insn = (insn << 8) | unwind_get_byte(ctrl); + mask = insn & 0x0fff; + if (mask == 0) + { + LOG_W("unwind: 'Refuse to unwind' instruction %04lx", + insn); + return -URC_FAILURE; + } + + ret = unwind_exec_pop_subset_r4_to_r13(ctrl, mask); + if (ret) + goto error; + } + else if ((insn & 0xf0) == 0x90 && + (insn & 0x0d) != 0x0d) + ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f]; + else if ((insn & 0xf0) == 0xa0) + { + ret = unwind_exec_pop_r4_to_rN(ctrl, insn); + if (ret) + goto error; + } + else if (insn == 0xb0) + { + if (ctrl->vrs[PC] == 0) + ctrl->vrs[PC] = ctrl->vrs[LR]; + /* no further processing */ + ctrl->entries = 0; + } + else if (insn == 0xb1) + { + unsigned long mask = unwind_get_byte(ctrl); + + if (mask == 0 || mask & 0xf0) + { + LOG_W("unwind: Spare encoding %04lx", + (insn << 8) | mask); + return -URC_FAILURE; + } + + ret = unwind_exec_pop_subset_r0_to_r3(ctrl, mask); + if (ret) + goto error; + } + else if (insn == 0xb2) + { + unsigned long uleb128 = unwind_get_byte(ctrl); + + ctrl->vrs[SP] += 0x204 + (uleb128 << 2); + } + else + { + LOG_W("unwind: Unhandled instruction %02lx", insn); + return -URC_FAILURE; + } + + LOG_D("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx", __func__, + ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]); + +error: + return ret; +} + +#ifdef RT_BACKTRACE_FUNCTION_NAME +static char *unwind_get_function_name(void *address) +{ + uint32_t flag_word = *(uint32_t *)((char*)address - 4); + + if ((flag_word & 0xff000000) == 0xff000000) + { + return (char *)((char*)address - 4 - (flag_word & 0x00ffffff)); + } + return RT_NULL; +} +#endif + +/* + * Unwind a single frame starting with *sp for the symbol at *pc. It + * updates the *pc and *sp with the new values. + */ +int unwind_frame(struct stackframe *frame, const struct unwind_idx **origin_idx, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]) +{ + unsigned long low; + const struct unwind_idx *idx; + struct unwind_ctrl_block ctrl; + struct rt_thread *rt_c_thread; + + /* store the highest address on the stack to avoid crossing it*/ + low = frame->sp; + rt_c_thread = rt_thread_self(); + ctrl.sp_high = (unsigned long)((char*)rt_c_thread->stack_addr + rt_c_thread->stack_size); + + LOG_D("%s(pc = %08lx lr = %08lx sp = %08lx)", __func__, + frame->pc, frame->lr, frame->sp); + + idx = unwind_find_idx(frame->pc, origin_idx, exidx_start, exidx_end); + if (!idx) + { + LOG_W("unwind: Index not found %08lx", frame->pc); + return -URC_FAILURE; + } + +#ifdef RT_BACKTRACE_FUNCTION_NAME + { + char *fun_name; + fun_name = unwind_get_function_name((void *)prel31_to_addr(&idx->addr_offset)); + if (fun_name) + { + rt_kprintf("0x%08x @ %s\n", frame->pc, fun_name); + } + } +#endif + + ctrl.vrs[FP] = frame->fp; + ctrl.vrs[SP] = frame->sp; + ctrl.vrs[LR] = frame->lr; + ctrl.vrs[PC] = 0; + + if (idx->insn == 1) + /* can't unwind */ + return -URC_FAILURE; + else if ((idx->insn & 0x80000000) == 0) + /* prel31 to the unwind table */ + ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn); + else if ((idx->insn & 0xff000000) == 0x80000000) + /* only personality routine 0 supported in the index */ + ctrl.insn = &idx->insn; + else + { + LOG_W("unwind: Unsupported personality routine %08lx in the index at %x", + idx->insn, idx); + return -URC_FAILURE; + } + + /* check the personality routine */ + if ((*ctrl.insn & 0xff000000) == 0x80000000) + { + ctrl.byte = 2; + ctrl.entries = 1; + } + else if ((*ctrl.insn & 0xff000000) == 0x81000000) + { + ctrl.byte = 1; + ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16); + } + else + { + LOG_W("unwind: Unsupported personality routine %08lx at %x", + *ctrl.insn, ctrl.insn); + return -URC_FAILURE; + } + + ctrl.check_each_pop = 0; + + while (ctrl.entries > 0) + { + int urc; + if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs)) + ctrl.check_each_pop = 1; + urc = unwind_exec_insn(&ctrl); + if (urc < 0) + return urc; + if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.sp_high) + return -URC_FAILURE; + } + + if (ctrl.vrs[PC] == 0) + ctrl.vrs[PC] = ctrl.vrs[LR]; + + /* check for infinite loop */ + if (frame->pc == ctrl.vrs[PC]) + return -URC_FAILURE; + + frame->fp = ctrl.vrs[FP]; + frame->sp = ctrl.vrs[SP]; + frame->lr = ctrl.vrs[LR]; + frame->pc = ctrl.vrs[PC]; + + return URC_OK; +} + +void unwind_backtrace(struct pt_regs *regs, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]) +{ + struct stackframe frame; + const struct unwind_idx *origin_idx = RT_NULL; + + LOG_D("%s(regs = %x)", __func__, regs); + + arm_get_current_stackframe(regs, &frame); + +#ifndef RT_BACKTRACE_FUNCTION_NAME + rt_kprintf("please use: addr2line -e rtthread.elf -a -f %08x\n", frame.pc); +#endif + LOG_D("pc = %08x, sp = %08x", frame.pc, frame.sp); + + while (1) + { + int urc; + + urc = unwind_frame(&frame, &origin_idx, exidx_start, exidx_end); + if (urc < 0) + break; + //dump_backtrace_entry(where, frame.pc, frame.sp - 4); +#ifndef RT_BACKTRACE_FUNCTION_NAME + rt_kprintf(" %08x", frame.pc); +#endif + LOG_D("from: pc = %08x, frame = %08x", frame.pc, frame.sp - 4); + } + rt_kprintf("\n"); +} + +extern const struct unwind_idx __exidx_start[]; +extern const struct unwind_idx __exidx_end[]; + +void rt_unwind(struct rt_hw_exp_stack *regs, unsigned int pc_adj) +{ + struct pt_regs e_regs; + + e_regs.ARM_fp = regs->fp; + e_regs.ARM_sp = regs->sp; + e_regs.ARM_lr = regs->lr; + e_regs.ARM_pc = regs->pc - pc_adj; +#ifdef RT_USING_SMART + if (!lwp_user_accessable((void *)e_regs.ARM_pc, sizeof (void *))) + { + e_regs.ARM_pc = regs->lr - sizeof(void *); + } +#endif + rt_kprintf("backtrace:\n"); + unwind_backtrace(&e_regs, __exidx_start, __exidx_end); +} + +rt_err_t rt_backtrace(void) +{ + struct rt_hw_exp_stack regs; + + __asm volatile ("mov %0, fp":"=r"(regs.fp)); + __asm volatile ("mov %0, sp":"=r"(regs.sp)); + __asm volatile ("mov %0, lr":"=r"(regs.lr)); + __asm volatile ("mov %0, pc":"=r"(regs.pc)); + rt_unwind(®s, 8); + return RT_EOK; +} +#endif // (__ICCARM__) undefined diff --git a/bsp/rdk/s100/startup/backtrace.h b/bsp/rdk/s100/startup/backtrace.h new file mode 100644 index 00000000000..5e03c2afa77 --- /dev/null +++ b/bsp/rdk/s100/startup/backtrace.h @@ -0,0 +1,83 @@ +#ifndef __BACKTRACE_H +#define __BACKTRACE_H + +#ifndef __ASSEMBLY__ +#include + +/* Unwind reason code according the the ARM EABI documents */ +enum unwind_reason_code +{ + URC_OK = 0, /* operation completed successfully */ + URC_CONTINUE_UNWIND = 8, + URC_FAILURE = 9 /* unspecified failure of some kind */ +}; + +struct unwind_idx +{ + unsigned long addr_offset; + unsigned long insn; +}; + +struct unwind_table +{ + const struct unwind_idx *start; + const struct unwind_idx *origin; + const struct unwind_idx *stop; + unsigned long begin_addr; + unsigned long end_addr; +}; + +struct stackframe +{ + /* + * FP member should hold R7 when CONFIG_THUMB2_KERNEL is enabled + * and R11 otherwise. + */ + unsigned long fp; + unsigned long sp; + unsigned long lr; + unsigned long pc; +}; + +struct pt_regs +{ + unsigned long uregs[18]; +}; + +#define ARM_cpsr uregs[16] +#define ARM_pc uregs[15] +#define ARM_lr uregs[14] +#define ARM_sp uregs[13] +#define ARM_ip uregs[12] +#define ARM_fp uregs[11] +#define ARM_r10 uregs[10] +#define ARM_r9 uregs[9] +#define ARM_r8 uregs[8] +#define ARM_r7 uregs[7] +#define ARM_r6 uregs[6] +#define ARM_r5 uregs[5] +#define ARM_r4 uregs[4] +#define ARM_r3 uregs[3] +#define ARM_r2 uregs[2] +#define ARM_r1 uregs[1] +#define ARM_r0 uregs[0] +#define ARM_ORIG_r0 uregs[17] + +#define instruction_pointer(regs) (regs)->ARM_pc + +#ifdef CONFIG_THUMB2_KERNEL +#define frame_pointer(regs) (regs)->ARM_r7 +#else +#define frame_pointer(regs) (regs)->ARM_fp +#endif + +int unwind_frame(struct stackframe *frame, const struct unwind_idx **origin_idx, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]); +void unwind_backtrace(struct pt_regs *regs, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]); + +void rt_unwind(struct rt_hw_exp_stack *regs, unsigned int pc_adj); +rt_err_t rt_backtrace(void); + +#endif /* !__ASSEMBLY__ */ + +#endif /* __BACKTRACE_H */ + diff --git a/bsp/rdk/s100/startup/context_gcc.S b/bsp/rdk/s100/startup/context_gcc.S new file mode 100644 index 00000000000..dec78f0fb76 --- /dev/null +++ b/bsp/rdk/s100/startup/context_gcc.S @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-03-01 Wangyuqiang first version + */ + +#include "rtconfig.h" + +.syntax unified +.text + +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_hw_trap_irq + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mrs r0, cpsr + cpsid i + bx lr + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + msr cpsr, r0 + bx lr + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) + * r0 --> from + * r1 --> to + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + clrex + stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) + stmfd sp!, {r0-r12, lr} @ push lr & register file + + mrs r4, cpsr + tst lr, #0x01 + orrne r4, r4, #0x20 @ it's thumb code + + stmfd sp!, {r4} @ push cpsr + +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq __no_vfp_frame1 + vstmdb sp!, {d0-d15} + vmrs r5, fpscr + stmfd sp!, {r5} +__no_vfp_frame1: + stmfd sp!, {r6} +#endif + str sp, [r0] @ store sp in preempted tasks TCB + ldr sp, [r1] @ get new task stack pointer + +#ifdef RT_USING_FPU + /* fpu context */ + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq __no_vfp_frame2 + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d0-d15} +__no_vfp_frame2: +#endif + + ldmfd sp!, {r1} + msr spsr_cxsf, r1 /* original mode */ + + ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ + +/* + * void rt_hw_context_switch_to(rt_uint32 to) + * r0 --> to + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + LDR sp, [r0] @ get new task stack pointer + +#ifdef RT_USING_FPU + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq __no_vfp_frame_to + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d0-d15} +__no_vfp_frame_to: +#endif + + LDMIA sp!, {r4} @ pop new task cpsr to spsr + MSR spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)@ + */ + +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + LDR r2, =rt_thread_switch_interrupt_flag + LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch + MOV r3, #1 @ set rt_thread_switch_interrupt_flag to 1 + STR r3, [r2] + LDR r2, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + + STR r0, [r2] +_reswitch: + LDR r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread + STR r1, [r2] + BX lr + +.globl IRQ_Handler +IRQ_Handler: + STMDB sp!, {r0-r12,lr} + +#ifdef RT_USING_FPU + VMRS r0, fpexc + TST r0, #0x40000000 + BEQ __no_vfp_frame_str_irq + VSTMDB sp!, {d0-d15} + VMRS r1, fpscr + @ TODO: add support for Common VFPv3. + @ Save registers like FPINST, FPINST2 + STMDB sp!, {r1} +__no_vfp_frame_str_irq: + STMDB sp!, {r0} +#endif + + BL rt_interrupt_enter + BL rt_hw_trap_irq + BL rt_interrupt_leave + + @ if rt_thread_switch_interrupt_flag set, jump to + @ rt_hw_context_switch_interrupt_do and don't return + LDR r0, =rt_thread_switch_interrupt_flag + LDR r1, [r0] + CMP r1, #1 + BEQ rt_hw_context_switch_interrupt_do + +#ifdef RT_USING_FPU + LDMIA sp!, {r0} @ get fpexc + VMSR fpexc, r0 + TST r0, #0x40000000 + BEQ __no_vfp_frame_ldr_irq + LDMIA sp!, {r1} @ get fpscr + VMSR fpscr, r1 + VLDMIA sp!, {d0-d15} +__no_vfp_frame_ldr_irq: +#endif + + LDMIA sp!, {r0-r12,lr} + SUBS pc, lr, #4 + +/* + * void rt_hw_context_switch_interrupt_do(rt_base_t flag) + */ +.globl rt_hw_context_switch_interrupt_do +rt_hw_context_switch_interrupt_do: + MOV r1, #0 @ clear flag + STR r1, [r0] + +#ifdef RT_USING_FPU + LDMIA sp!, {r0} @ get fpexc + VMSR fpexc, r0 + TST r0, #0x40000000 + BEQ __no_vfp_frame_do1 + LDMIA sp!, {r1} @ get fpscr + VMSR fpscr, r1 + VLDMIA sp!, {d0-d15} +__no_vfp_frame_do1: +#endif + + LDMIA sp!, {r0-r12,lr} @ reload saved registers + STMDB sp, {r0-r3} @ save r0-r3. We will restore r0-r3 in the SVC + @ mode so there is no need to update SP. + SUB r1, sp, #16 @ save the right SP value in r1, so we could restore r0-r3. + SUB r2, lr, #4 @ save old task's pc to r2 + + MRS r3, spsr @ get cpsr of interrupt thread + + @ switch to SVC mode and no interrupt + CPSID IF, #0x13 + + STMDB sp!, {r2} @ push old task's pc + STMDB sp!, {r4-r12,lr} @ push old task's lr,r12-r4 + LDMIA r1!, {r4-r7} @ restore r0-r3 of the interrupted thread + STMDB sp!, {r4-r7} @ push old task's r3-r0. We don't need to push/pop them to + @ r0-r3 because we just want to transfer the data and don't + @ use them here. + STMDB sp!, {r3} @ push old task's cpsr + +#ifdef RT_USING_FPU + VMRS r0, fpexc + TST r0, #0x40000000 + BEQ __no_vfp_frame_do2 + VSTMDB sp!, {d0-d15} + VMRS r1, fpscr + @ TODO: add support for Common VFPv3. + @ Save registers like FPINST, FPINST2 + STMDB sp!, {r1} +__no_vfp_frame_do2: + STMDB sp!, {r0} +#endif + + LDR r4, =rt_interrupt_from_thread + LDR r5, [r4] + STR sp, [r5] @ store sp in preempted tasks's TCB + + LDR r6, =rt_interrupt_to_thread + LDR r6, [r6] + LDR sp, [r6] @ get new task's stack pointer + +#ifdef RT_USING_FPU + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq __no_vfp_frame_do3 + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d0-d15} + +__no_vfp_frame_do3: +#endif + + LDMIA sp!, {r4} @ pop new task's cpsr to spsr + MSR spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ diff --git a/bsp/rdk/s100/startup/cp15.h b/bsp/rdk/s100/startup/cp15.h new file mode 100644 index 00000000000..0482ac31b6b --- /dev/null +++ b/bsp/rdk/s100/startup/cp15.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011-2024, Shanghai Real-Thread Electronic Technology Co.,Ltd + * + * Change Logs: + * Date Author Notes + * 2022-08-29 RT-Thread first version + */ + +#ifndef __CP15_H__ +#define __CP15_H__ + +#ifndef __DSB +#define __DSB() __asm volatile ("dsb" : : : "memory") +#endif + +#ifndef __ISB +#define __ISB() __asm volatile ("isb" : : : "memory") +#endif + +#define __get_cp(cp, op1, Rt, CRn, CRm, op2) \ + __asm volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_cp(cp, op1, Rt, CRn, CRm, op2) \ + __asm volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) +#define __get_cp64(cp, op1, Rt, CRm) \ + __asm volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) +#define __set_cp64(cp, op1, Rt, CRm) \ + __asm volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + +#endif diff --git a/bsp/rdk/s100/startup/cp15_gcc.S b/bsp/rdk/s100/startup/cp15_gcc.S new file mode 100644 index 00000000000..1d5b84d5961 --- /dev/null +++ b/bsp/rdk/s100/startup/cp15_gcc.S @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2011-2022, Shanghai Real-Thread Electronic Technology Co.,Ltd + * + * Change Logs: + * Date Author Notes + * 2022-08-29 RT-Thread first version + */ + + +.globl rt_cpu_get_smp_id +rt_cpu_get_smp_id: + mrc p15, #0, r0, c0, c0, #5 + bx lr + +.globl rt_cpu_vector_set_base +rt_cpu_vector_set_base: + /* clear SCTRL.V to customize the vector address */ + mrc p15, #0, r1, c1, c0, #0 + bic r1, #(1 << 13) + mcr p15, #0, r1, c1, c0, #0 + /* set up the vector address */ + mcr p15, #0, r0, c12, c0, #0 + dsb + bx lr + +.globl rt_hw_cpu_dcache_enable +rt_hw_cpu_dcache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_hw_cpu_icache_enable +rt_hw_cpu_icache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +_FLD_MAX_WAY: + .word 0x3ff +_FLD_MAX_IDX: + .word 0x7fff + +.globl rt_cpu_dcache_clean_flush +rt_cpu_dcache_clean_flush: +stmfd sp!, {r0-r12, lr} + bl v7_flush_dcache_all + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate + dsb + isb + ldmfd sp!, {r0-r12, lr} + mov pc, lr + +v7_flush_dcache_all: + dmb @ ensure ordering with previous memory accesses + mrc p15, 1, r0, c0, c0, 1 @ read clidr + ands r3, r0, #0x7000000 @ extract loc from clidr + mov r3, r3, lsr #23 @ left align loc bit field + beq finished @ if loc is 0, then no need to clean + mov r10, #0 @ start clean at cache level 0 +loop1: + add r2, r10, r10, lsr #1 @ work out 3x current cache level + mov r1, r0, lsr r2 @ extract cache type bits from clidr + and r1, r1, #7 @ mask of the bits for current cache only + cmp r1, #2 @ see what cache we have at this level + blt skip @ skip if no cache, or just i-cache + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + isb @ isb to sych the new cssr&csidr + mrc p15, 1, r1, c0, c0, 0 @ read the new csidr + and r2, r1, #7 @ extract the length of the cache lines + add r2, r2, #4 @ add 4 (line length offset) + ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 @ find maximum number on the way size + clz r5, r4 @ find bit position of way size increment + ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 @ extract max number of the index size +loop2: + mov r9, r4 @ create working copy of max way size +loop3: + orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 + orr r11, r11, r7, lsl r2 @ factor index number into r11 + mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way + subs r9, r9, #1 @ decrement the way + bge loop3 + subs r7, r7, #1 @ decrement the index + bge loop2 +skip: + add r10, r10, #2 @ increment cache number + cmp r3, r10 + bgt loop1 +finished: + mov r10, #0 @ swith back to cache level 0 + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + dsb + isb + mov pc, lr +#if 0 + push {r4-r11} + dmb + mrc p15, #1, r0, c0, c0, #1 @ read clid register + ands r3, r0, #0x7000000 @ get level of coherency + mov r3, r3, lsr #23 + beq finished + mov r10, #0 +loop1: + add r2, r10, r10, lsr #1 + mov r1, r0, lsr r2 + and r1, r1, #7 + cmp r1, #2 + blt skip + mcr p15, #2, r10, c0, c0, #0 + isb + mrc p15, #1, r1, c0, c0, #0 + and r2, r1, #7 + add r2, r2, #4 + ldr r4, _FLD_MAX_WAY + ands r4, r4, r1, lsr #3 + clz r5, r4 + ldr r7, _FLD_MAX_IDX + ands r7, r7, r1, lsr #13 +loop2: + mov r9, r4 +loop3: + orr r11, r10, r9, lsl r5 + orr r11, r11, r7, lsl r2 + mcr p15, #0, r11, c7, c14, #2 + subs r9, r9, #1 + bge loop3 + subs r7, r7, #1 + bge loop2 +skip: + add r10, r10, #2 + cmp r3, r10 + bgt loop1 + +finished: + dsb + isb + pop {r4-r11} + bx lr +#endif +.globl rt_cpu_icache_flush +rt_cpu_icache_flush: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate + dsb + isb + bx lr + +.globl rt_hw_cpu_dcache_disable +rt_hw_cpu_dcache_disable: + push {r4-r11, lr} + bl rt_cpu_dcache_clean_flush + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + pop {r4-r11, lr} + bx lr + +.globl rt_hw_cpu_icache_disable +rt_hw_cpu_icache_disable: + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr diff --git a/bsp/rdk/s100/startup/cpuport.c b/bsp/rdk/s100/startup/cpuport.c new file mode 100644 index 00000000000..5fce3d051a1 --- /dev/null +++ b/bsp/rdk/s100/startup/cpuport.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011-2024, Shanghai Real-Thread Electronic Technology Co.,Ltd + * + * Change Logs: + * Date Author Notes + * 2022-08-29 RT-Thread first version + */ + +#include +#include + +int rt_hw_cpu_id(void) +{ + int cpu_id; + __asm volatile ( + "mrc p15, 0, %0, c0, c0, 5" + :"=r"(cpu_id) + ); + cpu_id &= 0xf; + return cpu_id; +} + +rt_uint64_t get_main_cpu_affval(void) +{ + rt_uint32_t mpidr; + + __asm volatile ( + "mrc p15, 0, %0, c0, c0, 5" + : "=r"(mpidr) + ); + + /* + * GICv3 IROUTER uses Aff3:Aff2:Aff1:Aff0. On this AArch32 port we only + * need the MPIDR affinity fields already provided by the core. + */ + return (rt_uint64_t)(mpidr & 0x00FFFFFFU); +} + +/** + * @addtogroup ARM CPU + */ +/*@{*/ + +/** shutdown CPU */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} + +/*@}*/ diff --git a/bsp/rdk/s100/startup/cpuport.h b/bsp/rdk/s100/startup/cpuport.h new file mode 100644 index 00000000000..8b408e054cf --- /dev/null +++ b/bsp/rdk/s100/startup/cpuport.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2011-2024, Shanghai Real-Thread Electronic Technology Co.,Ltd + * + * Change Logs: + * Date Author Notes + * 2022-08-29 RT-Thread first version + */ + + +#ifndef CPUPORT_H__ +#define CPUPORT_H__ + +/* the exception stack without VFP registers */ +struct rt_hw_exp_stack +{ + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long sp; + unsigned long lr; + unsigned long pc; + unsigned long cpsr; +}; + +struct rt_hw_stack +{ + unsigned long cpsr; + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long lr; + unsigned long pc; +}; + +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define MONITORMODE 0x16 +#define ABORTMODE 0x17 +#define HYPMODE 0x1b +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 + +#define T_Bit (1<<5) +#define F_Bit (1<<6) +#define I_Bit (1<<7) +#define A_Bit (1<<8) +#define E_Bit (1<<9) +#define J_Bit (1<<24) + + +// rt_inline void rt_hw_isb(void) +// { +// __asm volatile ("isb":::"memory"); +// } + +// rt_inline void rt_hw_dmb(void) +// { +// __asm volatile ("dmb":::"memory"); +// } + +// rt_inline void rt_hw_dsb(void) +// { +// __asm volatile ("dsb":::"memory"); +// } + +#endif /*CPUPORT_H__*/ diff --git a/bsp/rdk/s100/startup/gicv3.c b/bsp/rdk/s100/startup/gicv3.c new file mode 100644 index 00000000000..e1d71450612 --- /dev/null +++ b/bsp/rdk/s100/startup/gicv3.c @@ -0,0 +1,830 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2014-04-03 Grissiom many enhancements + * 2018-11-22 Jesven add rt_hw_ipi_send() + * add rt_hw_ipi_handler_install() + */ + +#include +#include + +#include "gicv3.h" +#include "cp15.h" + +#ifndef RT_CPUS_NR +#define RT_CPUS_NR 1 +#endif + +struct arm_gic_v3 +{ + rt_uint32_t offset; /* the first interrupt index in the vector table */ + rt_uint32_t redist_hw_base[RT_CPUS_NR]; /* the pointer of the gic redistributor */ + rt_uint32_t dist_hw_base; /* the base address of the gic distributor */ + rt_uint32_t cpu_hw_base[RT_CPUS_NR]; /* the base addrees of the gic cpu interface */ +}; + +/* 'ARM_GIC_MAX_NR' is the number of cores */ +static struct arm_gic_v3 _gic_table[ARM_GIC_MAX_NR]; +static unsigned int _gic_max_irq; + +static rt_bool_t arm_gic_irq_is_valid(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + if ((irq < 0) || ((rt_uint32_t)irq >= _gic_max_irq)) + { + return RT_FALSE; + } + + return s100_board_irq_is_supported(irq); +} + +static rt_uint64_t arm_gic_cpumask_to_irouter_affinity(unsigned int cpumask) +{ + rt_uint64_t aff = get_main_cpu_affval(); + unsigned int aff0 = 0U; + + while (((cpumask & 0x1U) == 0U) && (aff0 < 32U)) + { + cpumask >>= 1; + aff0++; + } + + aff &= ~0xFFULL; + aff |= (rt_uint64_t)aff0; + return aff; +} + +/** + * @name: arm_gic_cpumask_to_affval + * @msg: + * @in param cpu_mask: + * @out param cluster_id: aff1 [0:7],aff2 [8:15],aff3 [16:23] + * @out param target_list: Target List. The set of PEs for which SGI interrupts will be generated. Each bit corresponds to the + * PE within a cluster with an Affinity 0 value equal to the bit number. + * @return {rt_uint32_t} 0 is finish , 1 is data valid + */ +rt_weak rt_uint32_t arm_gic_cpumask_to_affval(rt_uint32_t *cpu_mask, rt_uint32_t *cluster_id, rt_uint32_t *target_list) +{ + return 0; +} + +rt_weak rt_uint64_t get_main_cpu_affval(void) +{ + return 0; +} + +int arm_gic_get_active_irq(rt_uint32_t index) +{ + int irq; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + __get_gicv3_reg(ICC_IAR1, irq); + + irq = (irq & 0x1FFFFFF) + _gic_table[index].offset; + return irq; +} + +void arm_gic_ack(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT(irq >= 0); + + __DSB(); + __set_gicv3_reg(ICC_EOIR1, irq); +} + +void arm_gic_mask(rt_uint32_t index, int irq) +{ + rt_uint32_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + + mask = 1U << (irq % 32U); + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + if (irq < 32) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + GIC_RDISTSGI_ICENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask; + } + else + { + GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +void arm_gic_umask(rt_uint32_t index, int irq) +{ + rt_uint32_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + mask = 1U << (irq % 32U); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + if (irq < 32) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + GIC_RDISTSGI_ISENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask; + } + else + { + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq) +{ + rt_uint32_t pend; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return 0U; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + if (irq >= 16) + { + pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; + /* No CPU identification offered */ + if (pend != 0U) + { + pend = 1U; + } + else + { + pend = 0U; + } + } + + return (pend); +} + +void arm_gic_set_pending_irq(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + if (irq >= 16) + { + GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1U << (irq % 32U); + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + /* Forward the interrupt to the CPU interface that requested it */ + GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000U); + } +} + +void arm_gic_clear_pending_irq(rt_uint32_t index, int irq) +{ + rt_uint32_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + if (irq >= 16U) + { + mask = 1U << (irq % 32U); + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + } + else + { + mask = 1U << ((irq % 4U) * 8U); + GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +void arm_gic_set_configuration(rt_uint32_t index, int irq, rt_uint32_t config) +{ + rt_uint32_t icfgr; + rt_uint32_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq); + shift = (irq % 16U) << 1U; + + icfgr &= (~(3U << shift)); + icfgr |= ((config & 0x1U) << (shift + 1U)); + + GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr; +} + +rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return 0U; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> (((irq % 16U) << 1U) + 1U)) & 0x1U; +} + +void arm_gic_clear_active(rt_uint32_t index, int irq) +{ + rt_uint32_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + + mask = 1U << (irq % 32U); + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +/* Set up the cpu mask for the specific interrupt */ +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask) +{ + rt_uint64_t aff; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + if (irq < 32U) + { + /* + * SGI/PPI are redistributor-local resources; their target CPU is not + * configured through IROUTER. + */ + return; + } + + if (cpumask == 0U) + { + return; + } + + aff = arm_gic_cpumask_to_irouter_affinity(cpumask); + GIC_DIST_IROUTER_LOW(_gic_table[index].dist_hw_base, irq) = (rt_uint32_t)aff; + GIC_DIST_IROUTER_HIGH(_gic_table[index].dist_hw_base, irq) = (rt_uint32_t)(aff >> 32); +} + +rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq) +{ + rt_uint64_t aff; + rt_uint64_t main_aff; + rt_uint32_t aff0; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return 0U; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + if (irq < 32U) + { + return 1U << rt_hw_cpu_id(); + } + + aff = ((rt_uint64_t)GIC_DIST_IROUTER_HIGH(_gic_table[index].dist_hw_base, irq) << 32) | + (rt_uint64_t)GIC_DIST_IROUTER_LOW(_gic_table[index].dist_hw_base, irq); + main_aff = get_main_cpu_affval(); + + if ((aff & ~0xFFULL) != (main_aff & ~0xFFULL)) + { + return 0U; + } + + aff0 = (rt_uint32_t)(aff & 0xFFULL); + if (aff0 >= 32U) + { + return 0U; + } + + return 1U << aff0; +} + +void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority) +{ + rt_uint32_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + if (irq < 32U) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + + mask = GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq); + mask &= ~(0xFFUL << ((irq % 4U) * 8U)); + mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U)); + GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) = mask; + } + else + { + mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq); + mask &= ~(0xFFUL << ((irq % 4U) * 8U)); + mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U)); + GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return 0U; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + if (irq < 32U) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + RT_ASSERT((cpu_id) < RT_CPUS_NR); + return (GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) >> ((irq % 4U) * 8U)) & 0xFFUL; + } + else + { + return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; + } +} + +void arm_gic_set_system_register_enable_mask(rt_uint32_t index, rt_uint32_t value) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + value &= 0xFFUL; + /* set priority mask */ + __set_gicv3_reg(ICC_SRE, value); + __ISB(); +// __asm volatile ("isb 0xF":: +// :"memory"); +} + +rt_uint32_t arm_gic_get_system_register_enable_mask(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + rt_uint32_t value; + + __get_gicv3_reg(ICC_SRE, value); + return value; +} + +void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + priority &= 0xFFUL; + /* set priority mask */ + __set_gicv3_reg(ICC_PMR, priority); +} + +rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + rt_uint32_t priority; + + __get_gicv3_reg(ICC_PMR, priority); + return priority; +} + +void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point) +{ + index = index; + binary_point &= 0x7U; + + __set_gicv3_reg(ICC_BPR1, binary_point); +} + +rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index) +{ + rt_uint32_t binary_point; + + index = index; + __get_gicv3_reg(ICC_BPR1, binary_point); + return binary_point; +} + +rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq) +{ + rt_uint32_t pending; + rt_uint32_t active; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return 0U; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + + return ((active << 1U) | pending); +} + +rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index) +{ + rt_uint32_t irq; + RT_ASSERT(index < ARM_GIC_MAX_NR); + + index = index; + __get_gicv3_reg(ICC_HPPIR1, irq); + return irq; +} + +rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + return GIC_CPU_IIDR(_gic_table[index].cpu_hw_base); +} + +void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group) +{ + rt_uint32_t igroupr; + rt_uint32_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT(group <= 1U); + if (!arm_gic_irq_is_valid(index, irq)) + { + return; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq); + shift = (irq % 32U); + igroupr &= (~(1U << shift)); + igroupr |= ((group & 0x1U) << shift); + + GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr; +} + +rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + if (!arm_gic_irq_is_valid(index, irq)) + { + return 0U; + } + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq > 0U); + + return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; +} + +static int arm_gicv3_wait_rwp(rt_uint32_t index, rt_uint32_t irq) +{ + rt_uint32_t rwp_bit; + rt_uint32_t base; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + if (irq < 32u) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + RT_ASSERT((cpu_id) < RT_CPUS_NR); + base = _gic_table[index].redist_hw_base[cpu_id]; + rwp_bit = GICR_CTLR_RWP; + } + else + { + base = _gic_table[index].dist_hw_base; + rwp_bit = GICD_CTLR_RWP; + } + + while (__REG32(base) & rwp_bit) + { + ; + } + + return 0; +} + +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) +{ + rt_uint64_t cpu0_affval; + unsigned int gic_type; + rt_size_t irq_index; + rt_uint32_t irq; + rt_uint32_t shift; + rt_uint32_t value; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].dist_hw_base = dist_base; + _gic_table[index].offset = irq_start; + + /* Find out how many interrupts are supported. */ + gic_type = GIC_DIST_TYPE(dist_base); + _gic_max_irq = ((gic_type & 0x1fU) + 1U) * 32U; + + /* + * The GIC only supports up to 1020 interrupt sources. + * Limit this to either the architected maximum, or the + * platform maximum. + */ + if (_gic_max_irq > 1020U) + _gic_max_irq = 1020U; + if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */ + _gic_max_irq = ARM_GIC_NR_IRQS; + + GIC_DIST_CTRL(dist_base) = 0x0U; + /* Wait for register write pending */ + arm_gicv3_wait_rwp(0, 32); + + cpu0_affval = get_main_cpu_affval(); + /* Only configure SPI interrupts that are declared by the current board. */ + for (irq_index = 0; irq_index < s100_mcu1_rt_irq_configs_count; irq_index++) + { + irq = (rt_uint32_t)s100_mcu1_rt_irq_configs[irq_index].irq_number; + if ((irq < 32U) || (irq >= _gic_max_irq)) + { + continue; + } + + shift = (irq % 16U) << 1U; + value = GIC_DIST_CONFIG(dist_base, irq); + value &= ~(3U << shift); + GIC_DIST_CONFIG(dist_base, irq) = value; + + GIC_DIST_IROUTER_LOW(dist_base, irq) = (rt_uint32_t)cpu0_affval; + GIC_DIST_IROUTER_HIGH(dist_base, irq) = (rt_uint32_t)(cpu0_affval >> 32); + + value = GIC_DIST_PRI(dist_base, irq); + value &= ~(0xFFUL << ((irq % 4U) * 8U)); + value |= (0xA0UL << ((irq % 4U) * 8U)); + GIC_DIST_PRI(dist_base, irq) = value; + + GIC_DIST_PENDING_CLEAR(dist_base, irq) = 1U << (irq % 32U); + GIC_DIST_ENABLE_CLEAR(dist_base, irq) = 1U << (irq % 32U); + GIC_DIST_IGROUP(dist_base, irq) |= 1U << (irq % 32U); + } + + arm_gicv3_wait_rwp(0, 32); + + /* + The Distributor control register (GICD_CTLR) must be configured to enable the interrupt groups and to set the routing mode. + Enable Affinity routing (ARE bits) The ARE bits in GICD_CTLR control whether affinity routing is enabled. + If affinity routing is not enabled, GICv3 can be configured for legacy operation. + Whether affinity routing is enabled or not can be controlled separately for Secure and Non-secure state. + Enables GICD_CTLR contains separate enable bits for Group 0, Secure Group 1 and Non-secure Group 1: + GICD_CTLR.EnableGrp1S enables distribution of Secure Group 1 interrupts. + GICD_CTLR.EnableGrp1NS enables distribution of Non-secure Group 1 interrupts. + GICD_CTLR.EnableGrp0 enables distribution of Group 0 interrupts. + */ + GIC_DIST_CTRL(dist_base) = GICD_CTLR_ARE_NS | GICD_CTLR_ENGRP1NS; + + return 0; +} + +int arm_gic_redist_address_set(rt_uint32_t index, rt_uint32_t redist_addr, rt_uint32_t cpu_id) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + _gic_table[index].redist_hw_base[cpu_id] = redist_addr; + + return 0; +} + +int arm_gic_cpu_interface_address_set(rt_uint32_t index, rt_uint32_t interface_addr, rt_uint32_t cpu_id) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + _gic_table[index].cpu_hw_base[cpu_id] = interface_addr; + + return 0; +} + +int arm_gic_redist_init(rt_uint32_t index) +{ + unsigned int i; + rt_uint32_t base; + rt_int32_t cpu_id = rt_hw_cpu_id(); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + + base = _gic_table[index].redist_hw_base[cpu_id]; + /* redistributor enable */ + // 将原来的值的第二位清零,其他位保持不变 + GIC_RDIST_WAKER(base) &= ~(1U << 1); + // 一直执行,直到GIC_RDIST_WAKER(base)的值的第2位(从0开始计数)为0 + while (GIC_RDIST_WAKER(base) & (1 << 2)) + { + ; + } + + /* Disable all sgi and ppi interrupt */ + GIC_RDISTSGI_ICENABLER0(base) = 0xFFFFFFFF; + arm_gicv3_wait_rwp(0, 0); + + /* Clear all inetrrupt pending */ + GIC_RDISTSGI_ICPENDR0(base) = 0xFFFFFFFF; + + /* the corresponding interrupt is Group 1 or Non-secure Group 1. */ + GIC_RDISTSGI_IGROUPR0(base, 0) = 0xFFFFFFFF; + GIC_RDISTSGI_IGRPMODR0(base, 0) = 0xFFFFFFFF; + + /* Configure default priorities for SGI 0:15 and PPI 16:31. */ + for (i = 0; i < 32; i += 4) + { + GIC_RDISTSGI_IPRIORITYR(base, i) = 0xa0a0a0a0U; + } + + /* Trigger level for PPI interrupts*/ + GIC_RDISTSGI_ICFGR1(base) = 0x0U; // PPI is level-sensitive. + return 0; +} + +int arm_gic_cpu_init(rt_uint32_t index) +{ + rt_uint32_t value; + RT_ASSERT(index < ARM_GIC_MAX_NR); + + /* The Priority Mask sets the minimum priority an + * interrupt must have in order to be forwarded to the PE. + */ + value = arm_gic_get_system_register_enable_mask(index); + value |= (1U << 0); + + arm_gic_set_system_register_enable_mask(index, value); + __set_gicv3_reg(ICC_CTLR, 0); + + arm_gic_set_interface_prior_mask(index, 0xFFU); + + /* Enable group1 interrupt */ + value = 0x1U; + __set_gicv3_reg(ICC_IGRPEN1, value); + + /* The Binary Point register is used + * for priority grouping and preemption. + */ + arm_gic_set_binary_point(0, 0); + + /* ICC_BPR0_EL1 determines the preemption group for both + Group 0 and Group 1 interrupts. + */ + value = 0x1U; + __set_gicv3_reg(ICC_CTLR, value); + + return 0; +} + +#ifdef RT_USING_SMP +void arm_gic_secondary_cpu_init(void) +{ + arm_gic_redist_init(0); + + arm_gic_cpu_init(0); +} +#endif + +void arm_gic_dump_type(rt_uint32_t index) +{ + unsigned int gic_type; + + gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); + rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", + (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4U) & 0xfUL, + _gic_table[index].dist_hw_base, + _gic_max_irq, + gic_type & (1U << 10U) ? "has" : "no", + gic_type); +} + +void arm_gic_dump(rt_uint32_t index) +{ + unsigned int k; + rt_size_t i; + rt_uint32_t irq; + + k = arm_gic_get_high_pending_irq(0); + rt_kprintf("--- high pending priority: %d(%08x)\n", k, k); + rt_kprintf("--- hw mask ---\n"); + for (i = 0; i < s100_mcu1_rt_irq_configs_count; i++) + { + irq = (rt_uint32_t)s100_mcu1_rt_irq_configs[i].irq_number; + if ((irq < 32U) || (irq >= _gic_max_irq)) + { + continue; + } + + rt_kprintf("irq %3u %-16s enable=%u\n", + irq, + s100_mcu1_rt_irq_configs[i].name, + (GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1U); + } + rt_kprintf("\n--- hw pending ---\n"); + for (i = 0; i < s100_mcu1_rt_irq_configs_count; i++) + { + irq = (rt_uint32_t)s100_mcu1_rt_irq_configs[i].irq_number; + if ((irq < 32U) || (irq >= _gic_max_irq)) + { + continue; + } + + rt_kprintf("irq %3u %-16s pending=%u\n", + irq, + s100_mcu1_rt_irq_configs[i].name, + (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1U); + } + rt_kprintf("\n--- hw active ---\n"); + for (i = 0; i < s100_mcu1_rt_irq_configs_count; i++) + { + irq = (rt_uint32_t)s100_mcu1_rt_irq_configs[i].irq_number; + if ((irq < 32U) || (irq >= _gic_max_irq)) + { + continue; + } + + rt_kprintf("irq %3u %-16s active=%u\n", + irq, + s100_mcu1_rt_irq_configs[i].name, + (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1U); + } + rt_kprintf("\n"); +} + +long gic_dump(void) +{ + arm_gic_dump_type(0); + arm_gic_dump(0); + + return 0; +} diff --git a/bsp/rdk/s100/startup/gicv3.h b/bsp/rdk/s100/startup/gicv3.h new file mode 100644 index 00000000000..e92c6cd9f7f --- /dev/null +++ b/bsp/rdk/s100/startup/gicv3.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + */ + +#ifndef __GIC_V3_H__ +#define __GIC_V3_H__ + +#include +#include + +#define __get_gicv3_reg(CR, Rt) __asm volatile("MRC " CR \ + : "=r"(Rt) \ + : \ + : "memory") +#define __set_gicv3_reg(CR, Rt) __asm volatile("MCR " CR \ + : \ + : "r"(Rt) \ + : "memory") + + +/* AArch32 System register interface to GICv3 */ +#define ICC_IAR0 "p15, 0, %0, c12, c8, 0" +#define ICC_IAR1 "p15, 0, %0, c12, c12, 0" +#define ICC_EOIR0 "p15, 0, %0, c12, c8, 1" +#define ICC_EOIR1 "p15, 0, %0, c12, c12, 1" +#define ICC_HPPIR0 "p15, 0, %0, c12, c8, 2" +#define ICC_HPPIR1 "p15, 0, %0, c12, c12, 2" +#define ICC_BPR0 "p15, 0, %0, c12, c8, 3" +#define ICC_BPR1 "p15, 0, %0, c12, c12, 3" +#define ICC_DIR "p15, 0, %0, c12, c11, 1" +#define ICC_PMR "p15, 0, %0, c4, c6, 0" +#define ICC_RPR "p15, 0, %0, c12, c11, 3" +#define ICC_CTLR "p15, 0, %0, c12, c12, 4" +#define ICC_MCTLR "p15, 6, %0, c12, c12, 4" +#define ICC_SRE "p15, 0, %0, c12, c12, 5" +#define ICC_HSRE "p15, 4, %0, c12, c9, 5" +#define ICC_MSRE "p15, 6, %0, c12, c12, 5" +#define ICC_IGRPEN0 "p15, 0, %0, c12, c12, 6" +#define ICC_IGRPEN1 "p15, 0, %0, c12, c12, 7" +#define ICC_MGRPEN1 "p15, 6, %0, c12, c12, 7" + +#define __REG32(x) (*((volatile unsigned int*)((rt_uint32_t)x))) + +#define ROUTED_TO_ALL (1) +#define ROUTED_TO_SPEC (0) + +/** Macro to access the Distributor Control Register (GICD_CTLR) +*/ +#define GICD_CTLR_RWP ((unsigned int)1<<31) +#define GICD_CTLR_E1NWF (1<<7) +#define GICD_CTLR_DS (1<<6) // 当两种安全模式被同时支持时,可以通过GICD_CTLR.DS==1关闭其中一个,只支持non-secure模式 +#define GICD_CTLR_ARE_NS (1<<5) +#define GICD_CTLR_ARE_S (1<<4) +#define GICD_CTLR_ENGRP1S (1<<2) // secure group 1 +#define GICD_CTLR_ENGRP1NS (1<<1) // non-secure group 1 +#define GICD_CTLR_ENGRP0 (1<<0) // group 0 + +/** Macro to access the Redistributor Control Register (GICR_CTLR) +*/ +#define GICR_CTLR_UWP (1<<31) +#define GICR_CTLR_DPG1S (1<<26) +#define GICR_CTLR_DPG1NS (1<<25) +#define GICR_CTLR_DPG0 (1<<24) +#define GICR_CTLR_RWP (1<<3) +#define GICR_CTLR_IR (1<<2) +#define GICR_CTLR_CES (1<<1) +#define GICR_CTLR_EnableLPI (1<<0) + +/** Macro to access the Generic Interrupt Controller Interface (GICC) +*/ +#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00U) +#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04U) +#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08U) +#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0cU) +#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10U) +#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14U) +#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18U) +#define GIC_CPU_IIDR(hw_base) __REG32((hw_base) + 0xFCU) + +/** Macro to access the Generic Interrupt Controller Distributor (GICD) +*/ +#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) +#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004U) +#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380U + ((n)/32U) * 4U) +#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400U + ((n)/4U) * 4U) +#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800U + ((n)/4U) * 4U) +#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00U + ((n)/16U) * 4U) +#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00U) +#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10U + ((n)/4U) * 4U) +#define GIC_DIST_SPENDSGI(hw_base, n) __REG32((hw_base) + 0xf20U + ((n)/4U) * 4U) +#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8U) +#define GIC_DIST_IROUTER_LOW(hw_base, n) __REG32((hw_base) + 0x6000U + (n)*8U) +#define GIC_DIST_IROUTER_HIGH(hw_base, n) __REG32((hw_base) + 0x6000U + (n)*8U + 4) + +/* SGI base address is at 64K offset from Redistributor base address */ +#define GIC_RSGI_OFFSET 0x10000 + +/** Macro to access the Generic Interrupt Controller Redistributor (GICD) +*/ +#define GIC_RDIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) +#define GIC_RDIST_IIDR(hw_base) __REG32((hw_base) + 0x004U) +#define GIC_RDIST_TYPER(hw_base) __REG32((hw_base) + 0x008U) +#define GIC_RDIST_TSTATUSR(hw_base) __REG32((hw_base) + 0x010U) +#define GIC_RDIST_WAKER(hw_base) __REG32((hw_base) + 0x014U) +#define GIC_RDIST_SETLPIR(hw_base) __REG32((hw_base) + 0x040U) +#define GIC_RDIST_CLRLPIR(hw_base) __REG32((hw_base) + 0x048U) +#define GIC_RDIST_PROPBASER(hw_base) __REG32((hw_base) + 0x070U) +#define GIC_RDIST_PENDBASER(hw_base) __REG32((hw_base) + 0x078U) +#define GIC_RDIST_INVLPIR(hw_base) __REG32((hw_base) + 0x0A0U) +#define GIC_RDIST_INVALLR(hw_base) __REG32((hw_base) + 0x0B0U) +#define GIC_RDIST_SYNCR(hw_base) __REG32((hw_base) + 0x0C0U) + +#define GIC_RDISTSGI_IGROUPR0(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n)*4U) +#define GIC_RDISTSGI_ISENABLER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x100U) +#define GIC_RDISTSGI_ICENABLER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x180U) +#define GIC_RDISTSGI_ISPENDR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x200U) +#define GIC_RDISTSGI_ICPENDR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x280U) +#define GIC_RDISTSGI_ISACTIVER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x300U) +#define GIC_RDISTSGI_ICACTIVER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x380U) +#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U) +#define GIC_RDISTSGI_ICFGR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U) +#define GIC_RDISTSGI_ICFGR1(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U) +#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n)*4) +#define GIC_RDISTSGI_NSACR(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) // 当执行一个非安全模式到安全模式的访问 + +#define GIC_RSGI_AFF1_OFFSET 16 +#define GIC_RSGI_AFF2_OFFSET 32 +#define GIC_RSGI_AFF3_OFFSET 48 + +rt_uint32_t arm_gic_cpumask_to_affval(rt_uint32_t *cpu_mask, rt_uint32_t *cluster_id, rt_uint32_t *target_list); +rt_uint64_t get_main_cpu_affval(void); +int arm_gic_get_active_irq(rt_uint32_t index); +void arm_gic_ack(rt_uint32_t index, int irq); + +void arm_gic_mask(rt_uint32_t index, int irq); +void arm_gic_umask(rt_uint32_t index, int irq); + +rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq); +void arm_gic_set_pending_irq(rt_uint32_t index, int irq); +void arm_gic_clear_pending_irq(rt_uint32_t index, int irq); + +void arm_gic_set_configuration(rt_uint32_t index, int irq, rt_uint32_t config); +rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq); + +void arm_gic_clear_active(rt_uint32_t index, int irq); + +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask); +rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq); + +void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority); +rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq); + +void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority); +rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index); + +void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point); +rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index); + +rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq); + +rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index); + +rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index); + +void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group); +rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq); + +int arm_gic_redist_address_set(rt_uint32_t index, rt_uint32_t redist_addr, rt_uint32_t cpu_id); +int arm_gic_cpu_interface_address_set(rt_uint32_t index, rt_uint32_t interface_addr, rt_uint32_t cpu_id); +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start); +int arm_gic_cpu_init(rt_uint32_t index); +int arm_gic_redist_init(rt_uint32_t index); + +void arm_gic_dump_type(rt_uint32_t index); +void arm_gic_dump(rt_uint32_t index); + +void arm_gic_set_system_register_enable_mask(rt_uint32_t index, rt_uint32_t value); +rt_uint32_t arm_gic_get_system_register_enable_mask(rt_uint32_t index); +void arm_gic_secondary_cpu_init(void); + +void assemb_dsb_func(); +void assemb_isb_func(); + +#endif + diff --git a/bsp/rdk/s100/startup/interrupt.c b/bsp/rdk/s100/startup/interrupt.c new file mode 100644 index 00000000000..3306e4f9651 --- /dev/null +++ b/bsp/rdk/s100/startup/interrupt.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard first version + * 2018-11-22 Jesven add smp support + */ + +#include +#include +#include "interrupt.h" + +#include "gicv3.h" + +/* exception and interrupt handler table */ +struct rt_irq_desc isr_table[MAX_HANDLERS]; + +#ifndef RT_USING_SMP +/* Those varibles will be accessed in ISR, so we need to share them. */ +rt_uint32_t rt_interrupt_from_thread = 0; +rt_uint32_t rt_interrupt_to_thread = 0; +rt_uint32_t rt_thread_switch_interrupt_flag = 0; + +#ifdef RT_USING_HOOK +static void (*rt_interrupt_switch_hook)(void); + +void rt_interrupt_switch_sethook(void (*hook)(void)) +{ + rt_interrupt_switch_hook = hook; +} +#endif + +void rt_interrupt_hook(void) +{ + RT_OBJECT_HOOK_CALL(rt_interrupt_switch_hook, ()); +} +#endif + +const unsigned int VECTOR_BASE = 0x00; +extern void rt_cpu_vector_set_base(unsigned int addr); +extern int system_vectors; + +void rt_hw_vector_init(void) +{ + rt_cpu_vector_set_base((unsigned int)&system_vectors); +} + +/** + * This function will initialize hardware interrupt + * Called by the primary cpu(cpu0) + */ +void rt_hw_interrupt_init(void) +{ + rt_uint32_t gic_redist_base; + rt_int32_t cpu_id; + + /* initialize vector table */ + /* rt_hw_vector_init(); */ + + /* initialize exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + /* initialize ARM GIC */ + gic_redist_base = platform_get_gic_redist_base(); + cpu_id = rt_hw_cpu_id(); + + arm_gic_dist_init(0, platform_get_gic_dist_base(), 0); + arm_gic_redist_address_set(0, gic_redist_base, cpu_id); + + arm_gic_cpu_init(0); + arm_gic_redist_init(0); +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + arm_gic_mask(0, vector); +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + arm_gic_umask(0, vector); +} + +/** + * This function returns the active interrupt number. + * @param none + */ +int rt_hw_interrupt_get_irq(void) +{ + return arm_gic_get_active_irq(0); +} + +/** + * This function acknowledges the interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_ack(int vector) +{ + arm_gic_ack(0, vector); +} + +/** + * This function set interrupt CPU targets. + * @param vector: the interrupt number + * cpu_mask: target cpus mask, one bit for one core + */ +void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask) +{ + arm_gic_set_cpu(0, vector, cpu_mask); +} + +/** + * This function get interrupt CPU targets. + * @param vector: the interrupt number + * @return target cpus mask, one bit for one core + */ +unsigned int rt_hw_interrupt_get_target_cpus(int vector) +{ + return arm_gic_get_target_cpu(0, vector); +} + +/** + * This function set interrupt triger mode. + * @param vector: the interrupt number + * mode: interrupt triger mode; 0: level triger, 1: edge triger + */ +void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode) +{ + arm_gic_set_configuration(0, vector, mode); +} + +/** + * This function get interrupt triger mode. + * @param vector: the interrupt number + * @return interrupt triger mode; 0: level triger, 1: edge triger + */ +unsigned int rt_hw_interrupt_get_triger_mode(int vector) +{ + return arm_gic_get_configuration(0, vector); +} + +/** + * This function set interrupt pending flag. + * @param vector: the interrupt number + */ +void rt_hw_interrupt_set_pending(int vector) +{ + arm_gic_set_pending_irq(0, vector); +} + +/** + * This function get interrupt pending flag. + * @param vector: the interrupt number + * @return interrupt pending flag, 0: not pending; 1: pending + */ +unsigned int rt_hw_interrupt_get_pending(int vector) +{ + return arm_gic_get_pending_irq(0, vector); +} + +/** + * This function clear interrupt pending flag. + * @param vector: the interrupt number + */ +void rt_hw_interrupt_clear_pending(int vector) +{ + arm_gic_clear_pending_irq(0, vector); +} + +/** + * This function set interrupt priority value. + * @param vector: the interrupt number + * priority: the priority of interrupt to set + */ +void rt_hw_interrupt_set_priority(int vector, unsigned int priority) +{ + arm_gic_set_priority(0, vector, priority); +} + +/** + * This function get interrupt priority. + * @param vector: the interrupt number + * @return interrupt priority value + */ +unsigned int rt_hw_interrupt_get_priority(int vector) +{ + return arm_gic_get_priority(0, vector); +} + +/** + * This function set priority masking threshold. + * @param priority: priority masking threshold + */ +void rt_hw_interrupt_set_priority_mask(unsigned int priority) +{ + arm_gic_set_interface_prior_mask(0, priority); +} + +/** + * This function get priority masking threshold. + * @param none + * @return priority masking threshold + */ +unsigned int rt_hw_interrupt_get_priority_mask(void) +{ + return arm_gic_get_interface_prior_mask(0); +} + +/** + * This function set priority grouping field split point. + * @param bits: priority grouping field split point + * @return 0: success; -1: failed + */ +int rt_hw_interrupt_set_prior_group_bits(unsigned int bits) +{ + int status; + + if (bits < 8) + { + arm_gic_set_binary_point(0, (7 - bits)); + status = 0; + } + else + { + status = -1; + } + + return (status); +} + +/** + * This function get priority grouping field split point. + * @param none + * @return priority grouping field split point + */ +unsigned int rt_hw_interrupt_get_prior_group_bits(void) +{ + unsigned int bp; + + bp = arm_gic_get_binary_point(0) & 0x07; + + return (7 - bp); +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} diff --git a/bsp/rdk/s100/startup/interrupt.h b/bsp/rdk/s100/startup/interrupt.h new file mode 100644 index 00000000000..804943ea96f --- /dev/null +++ b/bsp/rdk/s100/startup/interrupt.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard first version + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + +#define IRQ_MODE_TRIG_LEVEL (0x00) /* Trigger: level triggered interrupt */ +#define IRQ_MODE_TRIG_EDGE (0x01) /* Trigger: edge triggered interrupt */ + +void rt_hw_vector_init(void); + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(int vector); + +int rt_hw_interrupt_get_irq(void); +void rt_hw_interrupt_ack(int vector); + +void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask); +unsigned int rt_hw_interrupt_get_target_cpus(int vector); + +void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode); +unsigned int rt_hw_interrupt_get_triger_mode(int vector); + +void rt_hw_interrupt_set_pending(int vector); +unsigned int rt_hw_interrupt_get_pending(int vector); +void rt_hw_interrupt_clear_pending(int vector); + +void rt_hw_interrupt_set_priority(int vector, unsigned int priority); +unsigned int rt_hw_interrupt_get_priority(int vector); + +void rt_hw_interrupt_set_priority_mask(unsigned int priority); +unsigned int rt_hw_interrupt_get_priority_mask(void); + +int rt_hw_interrupt_set_prior_group_bits(unsigned int bits); +unsigned int rt_hw_interrupt_get_prior_group_bits(void); + +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +#endif + diff --git a/bsp/rdk/s100/startup/stack.c b/bsp/rdk/s100/startup/stack.c new file mode 100644 index 00000000000..e60ab891ac9 --- /dev/null +++ b/bsp/rdk/s100/startup/stack.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011-2024, Shanghai Real-Thread Electronic Technology Co.,Ltd + * + * Change Logs: + * Date Author Notes + * 2022-08-29 RT-Thread first version + */ + +#include "armv8.h" +#include +//#include + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_uint32_t *stk; + + stack_addr += sizeof(rt_uint32_t); + stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); + stk = (rt_uint32_t *)stack_addr; + *(--stk) = (rt_uint32_t)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0xdeadbeef; /* r12 */ + *(--stk) = 0xdeadbeef; /* r11 */ + *(--stk) = 0xdeadbeef; /* r10 */ + *(--stk) = 0xdeadbeef; /* r9 */ + *(--stk) = 0xdeadbeef; /* r8 */ + *(--stk) = 0xdeadbeef; /* r7 */ + *(--stk) = 0xdeadbeef; /* r6 */ + *(--stk) = 0xdeadbeef; /* r5 */ + *(--stk) = 0xdeadbeef; /* r4 */ + *(--stk) = 0xdeadbeef; /* r3 */ + *(--stk) = 0xdeadbeef; /* r2 */ + *(--stk) = 0xdeadbeef; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + /* cpsr */ + if ((rt_uint32_t)tentry & 0x01) + *(--stk) = SVCMODE | 0x20; /* thumb mode */ + else + *(--stk) = SVCMODE; /* arm mode */ + +#ifdef RT_USING_OSA + *(--stk) = 0; /* user lr */ + *(--stk) = 0; /* user sp*/ +#endif +#ifdef RT_USING_FPU + rt_uint32_t i; + + for (i = 0; i < 32; i++) + { + *(--stk) = 0; /* d0-d15 initial state */ + } + *(--stk) = 0; /* fpscr */ + *(--stk) = 0x40000000; /* eager-enable FPU for every new thread */ +#endif + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} + +/*@}*/ diff --git a/bsp/rdk/s100/startup/startup_gcc.S b/bsp/rdk/s100/startup/startup_gcc.S new file mode 100644 index 00000000000..350ad09957e --- /dev/null +++ b/bsp/rdk/s100/startup/startup_gcc.S @@ -0,0 +1,476 @@ +#include "rtconfig.h" + .text + .align 4 + .section ".EL2_core_exceptions_table", "ax" + .globl EL2_core_exceptions_table + .type EL2_core_exceptions_table, %function +EL2_core_exceptions_table: + b EL2_Reset_Handler /* Reset Handler */ + b EL2_Undefined_Handler /* Undefined Handler */ + b EL2_HVC_Handler /* SVCall Handler */ + b EL2_Prefetch_Handler /* Prefetch Handler */ + b EL2_Abort_Handler /* Abort Handler */ + b EL2_Trap_Handler /* Reserved */ + b EL2_IRQ_Handler /* IRQ Handler */ + b EL2_FIQ_Handler /* FIQ Handler */ + + .arm + .align 4 + .section ".EL1_core_exceptions_table", "ax" +EL1_core_exceptions_table: + b EL1_Reset_Handler + b Undefined_Handler + b SVC_Handler + b Prefetch_Handler + b Abort_Handler + b Reserved_Handler + b IRQ_Handler + b FIQ_Handler + +/* Reset Handler */ + .text + .align 4 + .section ".EL2_Reset_Handler", "ax" + .globl EL2_Reset_Handler + .type EL2_Reset_Handler, %function +EL2_Reset_Handler: + mov r0, #0 + mov r1, r0 + mov r2, r0 + mov r3, r0 + mov r4, r0 + mov r5, r0 + mov r6, r0 + mov r7, r0 + mov r8, r0 + mov r9, r0 + mov r10, r0 + mov r11, r0 + mov r12, r0 + +#ifdef RT_USING_FPU + mrc p15, #0x00, r2, c1, c0, #0x02 + orr r2, r2, #0xF00000 + mcr p15, #0x00, r2, c1, c0, #0x02 + + fmrx r2, fpexc + orr r2, r2, #0x40000000 + fmxr fpexc, r2 +#endif + + ldr r0, =0x23000003 + MCR p15, 0, r0, c15, c0, 0 + + /*---------------TCM Initialization-------------------*/ + ldr r0, =0x0A000000 /* ATCM base address */ + ldr r1, =0x00010000 /* TCM size: 64KB */ + mov r2, #0 /* Clear value */ +tcm_init_loop: + str r2, [r0], #4 /* Write and increment */ + subs r1, r1, #4 /* Decrement counter */ + bne tcm_init_loop /* Continue if not zero */ + dsb /* Data synchronization barrier */ + isb /* Instruction synchronization barrier */ + + b MPU_Init + +MPU_Init: + mrc p15, 4, r0, c1, c0, 0 /* Read HSCTLR */ + and r0, r0, #0xFFFFFFFE /* set HSCTLR.M bit to 0, disable EL2 MPU */ + mcr p15, 4, r0, c1, c0, 0 /* write HSCTLR */ + + mrc p15, 0, r0, c1, c0, 0 /* Read SCTLR */ + and r0, r0, #0xFFFFFFFE /* set SCTLR.M bit to 0, disable EL1 MPU */ + mcr p15, 0, r0, c1, c0, 0 /* write SCTLR */ + + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #(0x1 << 12) /*icache */ + orr r0, r0, #(0x1 << 2) /*dcache */ + mcr p15, 0, r0, c1, c0, 0 + +disalbe_mpu_region_loop: + mov r0, r3 /* select region */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + mrc p15, 4, r0, c6, c3, 1 /* Read From HPRLAR */ + and r0, r0, #0xFFFFFFFE + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + + mrc p15, 0, r0, c6, c3, 1 /* Read From PRLAR */ + and r0, r0, #0xFFFFFFFE + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + add r3, r3, #1 + cmp r3, #24 /* hsm has only 16 mpu regions */ + blt disalbe_mpu_region_loop + + /* region 0 cluster0/cluster1 tcm */ + /* normal memory attribute */ + ldr r0, =0 /* Region 0 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =0x08000000 /* Start address */ + orr r0, r0, #0x2 /* SH=0, AP=1, XN=0*/ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =0x0AFFFFFF /* End address */ + and r0, r0, #0xFFFFFFC0 + orr r0, r0, #0x3 /* AttrIndex=1, non-cacheable, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 1 mcu sram (uncacheable)---------------*/ + /* normal memory attribute */ + ldr r0, =1 /* Region 1 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =0x0C800000 /* Start address */ + orr r0, r0, #0x2 /* SH=0, AP=1, XN=0*/ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =0x0CAAFFFF /* End address */ + and r0, r0, #0xFFFFFFC0 + orr r0, r0, #0x3 /* AttrIndex=1, non-cacheable, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 2 image read-only (cacheable, executable)---------------*/ + /* 0x0CAB0000 ~ (__image_rw_start__ - 64), startup/text/rodata */ + ldr r0, =2 /* Region 2 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =0x0CAB0000 /* Start: FLASH_STARTUP (64-byte aligned) */ + orr r0, r0, #0x6 /* SH=0, AP=3, XN=0 */ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =__image_rw_start__ /* End address: __image_rw_start__ is 64-byte aligned */ + sub r0, r0, #0x40 /* Limit = __image_rw_start__ - 64 */ + orr r0, r0, #0x1 /* AttrIndex=0, cacheable, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 4 image read-write (cacheable, XN)----------------*/ + ldr r0, =4 /* Region 4 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =__image_rw_start__ /* __image_rw_start__ is 64-byte aligned */ + and r0, r0, #0xFFFFFFC0 /* Ensure 64-byte alignment */ + orr r0, r0, #0x12 /* SH=0, AP=1, XN=1 */ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =__image_rw_end__ /* End address: __image_rw_end__ is 64-byte aligned */ + sub r0, r0, #0x40 /* Limit = __image_rw_end__ - 64 */ + orr r0, r0, #0x1 /* AttrIndex=0, cacheable, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /* Keep __image_rw_end__ ~ OS_HEAP_START_ADDR unmapped as a guard gap. */ + + /*---------------region 5 RTOS heap (cacheable, XN)----------------*/ + ldr r0, =5 /* Region 5 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =OS_HEAP_START_ADDR /* OS_HEAP_START_ADDR is 64-byte aligned */ + and r0, r0, #0xFFFFFFC0 /* Ensure 64-byte alignment */ + orr r0, r0, #0x12 /* SH=0, AP=1, XN=1 */ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =OS_HEAP_END_ADDR /* End address: OS_HEAP_END_ADDR is 64-byte aligned */ + sub r0, r0, #0x40 /* Limit = OS_HEAP_END_ADDR - 64 */ + orr r0, r0, #0x1 /* AttrIndex=0, cacheable, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 11 shared/reserved SRAM (non-cacheable, XN)----------------*/ + ldr r0, =11 /* Region 11 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =OS_HEAP_END_ADDR /* OS_HEAP_END_ADDR is 64-byte aligned */ + and r0, r0, #0xFFFFFFC0 /* Ensure 64-byte alignment */ + orr r0, r0, #0x12 /* SH=0, AP=1, XN=1 */ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =0x0CDFFFFF /* End address */ + and r0, r0, #0xFFFFFFC0 + orr r0, r0, #0x3 /* AttrIndex=1, non-cacheable, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 6 internal gic & peripheral---------------*/ + /* device memory attribute */ + ldr r0, =6 /* Region 6 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =0x22000000 /* Start address */ + orr r0, r0, #0x13 /* SH=2, AP=1, XN=1*/ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =0x223FFFFF /* End address */ + sub r0, r0, #1 + and r0, r0, #0xFFFFFFC0 + orr r0, r0, #0x7 /* AttrIndex=3, device memory, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 7 peripheral---------------*/ + /* device memory attribute */ + ldr r0, =7 /* Region 7 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =0x23000000 /* Start address */ + orr r0, r0, #0x13 /* SH=2, AP=1, XN=1*/ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =0x2FFFFFFF /* End address */ + sub r0, r0, #1 + and r0, r0, #0xFFFFFFC0 + orr r0, r0, #0x7 /* AttrIndex=3, device memory, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 8 CPUSYS------------------*/ + ldr r0, =8 /* Region 8 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =0x30000000 /* Start address */ + orr r0, r0, #0x13 /* SH=2, AP=1, XN=1*/ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =0x3FFFFFFF /* End address */ + and r0, r0, #0xFFFFFFC0 + orr r0, r0, #0x7 /* AttrIndex=3, device memory, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 9 DDR-------------------*/ + ldr r0, =9 /* Region 9 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =0x80000000 /* Start address */ + orr r0, r0, #0x2 /* SH=0, AP=1, XN=0*/ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =0xFFFFFFFF /* End address */ + and r0, r0, #0xFFFFFFC0 + orr r0, r0, #0x3 /* AttrIndex=1, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------region 10 xspi-------------------*/ + /* device memory attribute */ + ldr r0, =10 /* Region 10 */ + mcr p15, 4, r0, c6, c2, 1 /* Write HPRSELR */ + mcr p15, 0, r0, c6, c2, 1 /* Write PRSELR */ + + ldr r0, =0x18000000 /* Start address */ + orr r0, r0, #0x13 /* SH=2, AP=1, XN=1*/ + mcr p15, 4, r0, c6, c3, 0 /* Write HPRBAR */ + mcr p15, 0, r0, c6, c3, 0 /* Write PRBAR */ + + ldr r0, =0x1FFFFFFF /* End address */ + and r0, r0, #0xFFFFFFC0 + orr r0, r0, #0x7 /* AttrIndex=3, device memory, enable region */ + mcr p15, 4, r0, c6, c3, 1 /* Write HPRLAR */ + mcr p15, 0, r0, c6, c3, 1 /* Write PRLAR */ + + /*---------------SET MAIR/HMAIR-------------------*/ + ldr r0, =0x44FF /* attr0(FF): normal memory, write-back non-transient */ + /* attr1(44): normal memory, non-cacheable */ + /* attr2~3(00): Device-nGnRnE memory */ + mcr p15, 4, r0, c10, c2, 0 /* Write HMAIR0 */ + mcr p15, 0, r0, c10, c2, 0 /* Write MAIR0 */ + + ldr r0, =0x04 /* attr4~7(04/00): Device-nGnRnE memory */ + mcr p15, 4, r0, c10, c2, 1 /* Write HMAIR1 */ + mcr p15, 0, r0, c10, c2, 1 /* Write MAIR1 */ + +mpu_enable: + mrc p15, 4, r0, c1, c0, 0 /* Read HSCTLR */ + orr r0, r0, #0x1 /* Enable MPU */ + dsb + mcr p15, 4, r0, c1, c0, 0 /* Write HSCTLR */ + isb + + mrc p15, 0, r0, c1, c0, 0 /* Read SCTLR */ + orr r0, r0, #0x1 /* Enable MPU */ + dsb + mcr p15, 0, r0, c1, c0, 0 /* Write SCTLR */ + isb + +/* ARMv8-R cores are in EL2 (hypervisor mode) after reset, and we need + to descend to EL1 (supervisor mode) or EL0 (user mode) */ + +/* Init HVBAR (Hypervisor Vector Base Address Register) */ + ldr r0, =EL2_core_exceptions_table + mcr p15, 4, r0, c12, c0, 0 /* Move to Coprocessor from ARM Register */ + +/* Init VBAR (Vector Base Address Register) */ + ldr r0, =EL1_core_exceptions_table + mcr p15, 0, r0, c12, c0, 0 /* Move to Coprocessor from ARM Register */ + +init_mcu_stack: + ldr r3, =__StackTop + mov SP, r3 + + bl init_bss + + /* Init ELR_hyp with EL1_Reset_Handler so eret can descend from EL2 to EL1. */ + ldr r0, =EL1_Reset_Handler + msr ELR_hyp, r0 + + mrs r0, SPSR_hyp + and r0, r0, #~0x00FF /* r0 = r0 & FFFF FFE0. Clear SPSR_hyp bits [4:0] -> Execution state bit + Mode bits. */ + + /* Return to EL1 system mode with interrupts masked until EL1 stack setup is done. */ + orr r0, r0, #0x1f + bic r0, r0, #(0x1 << 5) + msr SPSR_hyp, r0 + + /* Configure the GIC CPU Interface */ + /* Disable group 0 interrupts */ + mov r0, #0x00 + mcr p15, 0, r0, c12, c12, 6 /* Write to ICC_IGRPEN0 */ + + /* Enable group 1 interrupts */ + mov r0, #0x01 + mcr p15, 0, r0, c12, c12, 7 /* Write to ICC_IGRPEN1 */ + + /* Set the interrupt priority mask to biggest value - 0x1F */ + /* Interrupts with all priorities are allowed. */ + + mov r0, #0xF8 /* The priority bitfield is shifted with 3 bits - 0x1F becomes 0xF8 */ + mcr p15, 0, r0, c4, c6, 0 /* Write to ICC_PMR */ + + /* Set the binary point for group 0 and group 1 interrupts */ + mov r0, #0 + mcr p15, 0, r0, c12, c8, 3 /* Write to ICC_BPR0 */ + mcr p15, 0, r0, c12, c12, 3 /* Write to ICC_BPR1 */ + + /* Exception return - will jump to address pointed by ELR_hyp (main) */ + eret /* When executed in Hyp mode, ERET loads the PC from ELR_hyp and loads the CPSR from SPSR_hyp */ + + + .text + .align 4 + .globl EL1_Reset_Handler + .type EL1_Reset_Handler, %function +EL1_Reset_Handler: +/* Divide the non-USR mode stack area between the 5 non-USR modes */ + /* ABT,UND get 1/10 each. HYP, SVC,FIQ,IRQ get 1/5 each. */ + ldr r3, =__StackTop + ldr r2, =__StackLimit + sub r2, r3, r2 /* r2 : size in bytes */ + mov r4, #2 + udiv r1, r2, r4 /* r1 : size divided by 2 */ + and r1, r1, #~0x0f /* r1 size alligned to 16 bytes */ + + /* Setup the stack for supervisor mode (entered from reset) */ + mrs r0, cpsr + and r0, r0, #~0x00FF + orr r0, r0, #0x0033 + msr cpsr_c, r0 + sub r3, r3, r1 + mov SP, r3 /* top of stack to SP_svc */ + + ldr r3, =__StackTop_exc + ldr r2, =__StackLimit_exc + sub r2, r3, r2 /* r2 : size in bytes */ + mov r4, #4 + udiv r1, r2, r4 /* r1 : size divided by 4 */ + and r1, r1, #~0x0f /* r1 size alligned to 16 bytes */ + + /* Go to FIQ mode and set stack (below the previous one) */ + mrs r0, cpsr + and r0, r0, #~0x003F + orr r0, r0, #0x0031 + msr cpsr_c, r0 + sub r3, r3, r1 + mov SP, r3 + + /* Go to IRQ mode and set stack (below the previous one) */ + mrs r0, cpsr + and r0, r0, #~0x003F + orr r0, r0, #0x0032 + msr cpsr_c, r0 + sub r3, r3, r1 + mov SP, r3 + + /* Go to ABORT mode and set stack (below the previous one) */ + mrs r0, cpsr + and r0, r0, #~0x003F + orr r0, r0, #0x0037 + msr cpsr_c, r0 + sub r3, r3, r1 + mov SP, r3 + + /* Go to UNDEF mode and set stack (below the previous one) */ + mrs r0, cpsr + and r0, r0, #~0x003F + orr r0, r0, #0x003b + msr cpsr_c, r0 + sub r3, r3, r1 + mov SP, r3 + + /* Go to SYSTEM mode and set stack to the top of the reserved area */ + /* This is also the stack for user mode */ + mrs r0, cpsr + and r0, r0, #~0x003F + orr r0, r0, #0x003F + msr cpsr_c, r0 + + ldr r3, =__StackTop_exc + mov SP, r3 + + /* Enable IRQ and FIQ interrupts for the system/user mode */ + cpsie i /* Unmask interrupts (IRQ)*/ + cpsie f /* Unmask fast interrupts (FIQ)*/ + + /* Go to supervisor mode */ + mrs r0, cpsr + and r0, r0, #~0x00FF + orr r0, r0, #0x0033 + msr cpsr_c, r0 + /* Jump to the entry() method */ + bl entry + + /* Should never get here */ + b . + + .text + .align 4 + .globl init_bss + .type init_bss, %function +init_bss: + ldr r1, =__bss_start + ldr r2, =__bss_end + mov r0, #0 + +.clear_bss_loop: + cmp r1, r2 + bcs .init_done + str r0, [r1], #4 + b .clear_bss_loop + +.init_done: + bx lr diff --git a/bsp/rdk/s100/startup/system.c b/bsp/rdk/s100/startup/system.c new file mode 100644 index 00000000000..f32988df5f9 --- /dev/null +++ b/bsp/rdk/s100/startup/system.c @@ -0,0 +1,135 @@ +#include +#include "board.h" +#include "gicv3.h" + +/* MCU1 interrupt numbers extracted from the original SDK configuration. */ + +#define Os_IntChannel_PDMA0_Ch0Isr 213U +#define Os_IntChannel_Pps_IcuRtcIsr 221U +#define Os_IntChannel_Pps_IcuEthIsr 229U +#define Os_IntChannel_Spi0_Isr 171U +#define Os_IntChannel_Spi1_Isr 172U +#define Os_IntChannel_Spi2_Isr 173U +#define Os_IntChannel_Spi3_Isr 174U +#define Os_IntChannel_Uart4_Isr 45U +#define Os_IntChannel_Uart5_Isr 46U +#define Os_IntChannel_Adc_Ch0WdIsr 48U +#define Os_IntChannel_Adc_Ch1WdIsr 49U +#define Os_IntChannel_Adc_Ch2WdIsr 50U +#define Os_IntChannel_Adc_Ch3WdIsr 51U +#define Os_IntChannel_Adc_Ch4WdIsr 52U +#define Os_IntChannel_Adc_Ch5WdIsr 53U +#define Os_IntChannel_Adc_Ch6WdIsr 54U +#define Os_IntChannel_Adc_Ch7WdIsr 55U +#define Os_IntChannel_Adc_Ch8WdIsr 56U +#define Os_IntChannel_Adc_Ch9WdIsr 57U +#define Os_IntChannel_Adc_Ch10WdIsr 58U +#define Os_IntChannel_Adc_Ch11WdIsr 59U +#define Os_IntChannel_Adc_Ch12WdIsr 60U +#define Os_IntChannel_Adc_Ch13WdIsr 61U +#define Os_IntChannel_Adc_InjIsr 62U +#define Os_IntChannel_Adc_NorIsr 63U +#define Os_IntChannel_I2c0_Isr 64U +#define Os_IntChannel_I2c1_Isr 65U +#define Os_IntChannel_I2c2_Isr 66U +#define Os_IntChannel_I2c3_Isr 67U +#define Os_IntChannel_Gpio_Icu0ExtIsr 68U +#define Os_IntChannel_Gpio_Icu1ExtIsr 69U +#define Os_IntChannel_Gpio_Icu2ExtIsr 70U +#define Os_IntChannel_Mdma1_Ch1Isr 212U +#define Os_IntChannel_Ipc_CpuIpc0Ch0Isr 254U +#define Os_IntChannel_Ipc_CpuIpc0Ch4Isr 258U +#define Os_IntChannel_Ipc_CpuIpc0Ch7Isr 261U +#define Os_IntChannel_Ipc_CpuIpc0Ch10Isr 264U +#define Os_Cross_Core_Ins0_Isr 237U +#define Os_Cross_Core_Ins1_Isr 238U +#define Os_Cross_Core_Ins2_Isr 239U +#define Os_Cross_Core_Ins3_Isr 234U +#define Os_Cross_Core_Ins4_Isr 235U +#define Os_Cross_Core_Ins5_Isr 236U +#define Os_IntChannel_Can5_DataIsr 136U +#define Os_IntChannel_Can6_DataIsr 140U +#define Os_IntChannel_Can7_DataIsr 144U +#define Os_IntChannel_Can8_DataIsr 148U +#define Os_IntChannel_Can9_DataIsr 152U + +/* + * MCU1 interrupt whitelist extracted from the original SDK interrupt map. + * The current BSP only manages these SPI IDs; everything else is treated as + * out-of-scope to avoid colliding with resources still owned by MCU0. + */ + +const s100_rt_irq_config_t s100_mcu1_rt_irq_configs[] = +{ + {Os_IntChannel_PDMA0_Ch0Isr, RT_TRUE, "PDMA0_Ch0"}, + {Os_IntChannel_Pps_IcuRtcIsr, RT_TRUE, "Pps_IcuRtc"}, + {Os_IntChannel_Pps_IcuEthIsr, RT_TRUE, "Pps_IcuEth"}, + {Os_IntChannel_Spi0_Isr, RT_TRUE, "Spi0"}, + {Os_IntChannel_Spi1_Isr, RT_TRUE, "Spi1"}, + {Os_IntChannel_Spi2_Isr, RT_TRUE, "Spi2"}, + {Os_IntChannel_Spi3_Isr, RT_TRUE, "Spi3"}, + {Os_IntChannel_Uart4_Isr, RT_TRUE, "Uart4"}, + {Os_IntChannel_Uart5_Isr, RT_TRUE, "Uart5"}, + {Os_IntChannel_Adc_Ch0WdIsr, RT_TRUE, "Adc_Ch0Wd"}, + {Os_IntChannel_Adc_Ch1WdIsr, RT_TRUE, "Adc_Ch1Wd"}, + {Os_IntChannel_Adc_Ch2WdIsr, RT_TRUE, "Adc_Ch2Wd"}, + {Os_IntChannel_Adc_Ch3WdIsr, RT_TRUE, "Adc_Ch3Wd"}, + {Os_IntChannel_Adc_Ch4WdIsr, RT_TRUE, "Adc_Ch4Wd"}, + {Os_IntChannel_Adc_Ch5WdIsr, RT_TRUE, "Adc_Ch5Wd"}, + {Os_IntChannel_Adc_Ch6WdIsr, RT_TRUE, "Adc_Ch6Wd"}, + {Os_IntChannel_Adc_Ch7WdIsr, RT_TRUE, "Adc_Ch7Wd"}, + {Os_IntChannel_Adc_Ch8WdIsr, RT_TRUE, "Adc_Ch8Wd"}, + {Os_IntChannel_Adc_Ch9WdIsr, RT_TRUE, "Adc_Ch9Wd"}, + {Os_IntChannel_Adc_Ch10WdIsr, RT_TRUE, "Adc_Ch10Wd"}, + {Os_IntChannel_Adc_Ch11WdIsr, RT_TRUE, "Adc_Ch11Wd"}, + {Os_IntChannel_Adc_Ch12WdIsr, RT_TRUE, "Adc_Ch12Wd"}, + {Os_IntChannel_Adc_Ch13WdIsr, RT_TRUE, "Adc_Ch13Wd"}, + {Os_IntChannel_Adc_InjIsr, RT_TRUE, "Adc_Inj"}, + {Os_IntChannel_Adc_NorIsr, RT_TRUE, "Adc_Nor"}, + {Os_IntChannel_I2c0_Isr, RT_TRUE, "I2c0"}, + {Os_IntChannel_I2c1_Isr, RT_TRUE, "I2c1"}, + {Os_IntChannel_I2c2_Isr, RT_TRUE, "I2c2"}, + {Os_IntChannel_I2c3_Isr, RT_TRUE, "I2c3"}, + {Os_IntChannel_Gpio_Icu0ExtIsr, RT_TRUE, "Gpio_Icu0Ext"}, + {Os_IntChannel_Gpio_Icu1ExtIsr, RT_TRUE, "Gpio_Icu1Ext"}, + {Os_IntChannel_Gpio_Icu2ExtIsr, RT_TRUE, "Gpio_Icu2Ext"}, + {Os_IntChannel_Mdma1_Ch1Isr, RT_TRUE, "Mdma1_Ch1"}, + {Os_IntChannel_Ipc_CpuIpc0Ch0Isr, RT_TRUE, "Ipc_CpuIpc0Ch0"}, + {Os_IntChannel_Ipc_CpuIpc0Ch4Isr, RT_TRUE, "Ipc_CpuIpc0Ch4"}, + {Os_IntChannel_Ipc_CpuIpc0Ch7Isr, RT_TRUE, "Ipc_CpuIpc0Ch7"}, + {Os_IntChannel_Ipc_CpuIpc0Ch10Isr, RT_TRUE, "Ipc_CpuIpc0Ch10"}, + {Os_Cross_Core_Ins0_Isr, RT_TRUE, "Cross_Core_Ins0"}, + {Os_Cross_Core_Ins1_Isr, RT_TRUE, "Cross_Core_Ins1"}, + {Os_Cross_Core_Ins2_Isr, RT_TRUE, "Cross_Core_Ins2"}, + {Os_Cross_Core_Ins3_Isr, RT_TRUE, "Cross_Core_Ins3"}, + {Os_Cross_Core_Ins4_Isr, RT_TRUE, "Cross_Core_Ins4"}, + {Os_Cross_Core_Ins5_Isr, RT_TRUE, "Cross_Core_Ins5"}, + {Os_IntChannel_Can5_DataIsr, RT_TRUE, "Can5_Data"}, + {Os_IntChannel_Can6_DataIsr, RT_TRUE, "Can6_Data"}, + {Os_IntChannel_Can7_DataIsr, RT_TRUE, "Can7_Data"}, + {Os_IntChannel_Can8_DataIsr, RT_TRUE, "Can8_Data"}, + {Os_IntChannel_Can9_DataIsr, RT_TRUE, "Can9_Data"}, +}; + +const rt_size_t s100_mcu1_rt_irq_configs_count = + sizeof(s100_mcu1_rt_irq_configs) / sizeof(s100_mcu1_rt_irq_configs[0]); + +rt_bool_t s100_board_irq_is_supported(int irq) +{ + rt_size_t i; + + if ((irq >= 0) && (irq < 32)) + { + return RT_TRUE; + } + + for (i = 0; i < s100_mcu1_rt_irq_configs_count; i++) + { + if (s100_mcu1_rt_irq_configs[i].irq_number == irq) + { + return RT_TRUE; + } + } + + return RT_FALSE; +} diff --git a/bsp/rdk/s100/startup/trap.c b/bsp/rdk/s100/startup/trap.c new file mode 100644 index 00000000000..39bb2bece6c --- /dev/null +++ b/bsp/rdk/s100/startup/trap.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + */ + +#include +#include +#include +#include +//#include + +#include "interrupt.h" + +#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) +extern long list_thread(void); +#endif +extern void rt_unwind(struct rt_hw_exp_stack *regs, unsigned int pc_adj); +void (*rt_trap_hook)(struct rt_hw_exp_stack *regs, const char *ex, unsigned int exception_type); + +static void rt_hw_show_backtrace(struct rt_hw_exp_stack *regs) +{ + rt_unwind(regs, 0U); +} + +enum +{ + RT_HW_EL2_TRAP_UNDEF = 0, + RT_HW_EL2_TRAP_PABT, + RT_HW_EL2_TRAP_DABT, + RT_HW_EL2_TRAP_IRQ, + RT_HW_EL2_TRAP_FIQ, + RT_HW_EL2_TRAP_HVC, + RT_HW_EL2_TRAP_RESV, +}; + +void rt_hw_trap_el2(struct rt_hw_exp_stack *regs, unsigned int trap_id) +{ + const char *ex; + unsigned int exception_type; + + switch (trap_id) + { + case RT_HW_EL2_TRAP_UNDEF: + ex = "undefined instruction"; + exception_type = UND_EXCEPTION; + break; + case RT_HW_EL2_TRAP_PABT: + ex = "prefetch abort"; + exception_type = PABT_EXCEPTION; + break; + case RT_HW_EL2_TRAP_DABT: + ex = "data abort"; + exception_type = DABT_EXCEPTION; + break; + case RT_HW_EL2_TRAP_IRQ: + ex = "unexpected IRQ"; + exception_type = RESV_EXCEPTION; + break; + case RT_HW_EL2_TRAP_FIQ: + ex = "unexpected FIQ"; + exception_type = RESV_EXCEPTION; + break; + case RT_HW_EL2_TRAP_HVC: + ex = "unexpected HVC"; + exception_type = RESV_EXCEPTION; + break; + case RT_HW_EL2_TRAP_RESV: + default: + ex = "reserved trap"; + exception_type = RESV_EXCEPTION; + break; + } + + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("EL2 %s:\n", ex); + rt_hw_show_register(regs); + rt_hw_show_backtrace(regs); +#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) + list_thread(); +#endif + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, ex, exception_type); + } +} + +/** + * The software interrupt instruction (SWI) is used for entering + * Supervisor mode, usually to request a particular supervisor + * function. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_svc(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("software interrupt\n"); + rt_hw_show_register(regs); + rt_hw_show_backtrace(regs); +#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; + +/** + * This function set the hook, which is invoked on fault exception handling. + * + * @param exception_handle the exception handling hook function. + */ +void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)) +{ + rt_exception_hook = exception_handle; +} + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ +void rt_hw_show_register(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); + rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); + rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); + rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); + rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); + rt_kprintf("cpsr:0x%08x\n", regs->cpsr); + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } +} + +/** + * This function will set a hook function to trap handler. + * + * @param hook the hook function + */ +void rt_hw_trap_set_hook(void (*hook)(struct rt_hw_exp_stack *regs, const char *ex, unsigned int exception_type)) +{ + rt_trap_hook = hook; +} + +/** + * When comes across an instruction which it cannot handle, + * it takes the undefined instruction trap. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) +{ + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("undefined instruction:\n"); + rt_hw_show_register(regs); + rt_hw_show_backtrace(regs); +#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) + list_thread(); +#endif + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "undefined instruction", UND_EXCEPTION); + } +} + +/** + * The software interrupt instruction (SWI) is used for entering + * Supervisor mode, usually to request a particular supervisor + * function. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) +{ + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("software interrupt:\n"); + rt_hw_show_register(regs); + rt_hw_show_backtrace(regs); +#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) + list_thread(); +#endif + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "software instruction", SWI_EXCEPTION); + } +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during an instruction prefetch. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) +{ + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("prefetch abort:\n"); + rt_hw_show_register(regs); + rt_hw_show_backtrace(regs); +#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) + list_thread(); +#endif + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "prefetch abort", PABT_EXCEPTION); + } +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during a data access. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) +{ + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("data abort:"); + rt_hw_show_register(regs); + rt_hw_show_backtrace(regs); +#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) + list_thread(); +#endif + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "data abort", DABT_EXCEPTION); + } +} + +/** + * Normally, system will never reach here + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) +{ + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("reserved trap:\n"); + rt_hw_show_register(regs); + rt_hw_show_backtrace(regs); +#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) + list_thread(); +#endif + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "reserved trap", RESV_EXCEPTION); + } +} + +void rt_hw_trap_irq(void) +{ + void *param; + int int_ack; + int ir; + volatile rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + + int_ack = rt_hw_interrupt_get_irq(); + + ir = int_ack & GIC_ACK_INTID_MASK; + if (ir == 1023) + { + /* Spurious interrupt */ + return; + } + + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; + +#ifdef RT_USING_INTERRUPT_INFO + isr_table[ir].counter++; +#endif + if (isr_func) + { + /* Interrupt for myself. */ + param = isr_table[ir].param; + /* turn to interrupt service routine */ + isr_func(ir, param); + } + + /* end of interrupt */ + rt_hw_interrupt_ack(int_ack); +} + +void rt_hw_trap_fiq(void) +{ + void *param; + int ir; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + + ir = rt_hw_interrupt_get_irq(); + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; + param = isr_table[ir].param; + + /* turn to interrupt service routine */ + isr_func(ir, param); + + /* end of interrupt */ + rt_hw_interrupt_ack(ir); +} diff --git a/bsp/rdk/s100/startup/vector_gcc.S b/bsp/rdk/s100/startup/vector_gcc.S new file mode 100644 index 00000000000..64b4d7636bc --- /dev/null +++ b/bsp/rdk/s100/startup/vector_gcc.S @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + + + .globl turnon_VFP +turnon_VFP: + @ Enable FPV + STMDB sp!, {r0} + fmrx r0, fpexc + orr r0, r0, #0x40000000 + fmxr fpexc, r0 + LDMIA sp!, {r0} + subs pc, lr, #4 + + .macro push_svc_reg pc_adjust + sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + mov r0, sp + mrs r6, spsr @/* Save CPSR */ + sub r5, lr, #\pc_adjust + str r5, [r0, #15*4] @/* Push fault PC */ + str r6, [r0, #16*4] @/* Push CPSR */ + cps #0x13 @/* Switch to SVC mode */ + str sp, [r0, #13*4] @/* Save calling SP */ + str lr, [r0, #14*4] @/* Save calling PC */ + .endm + + /* + * EL2 exceptions are unexpected in the normal RT-Thread runtime because + * the core has already descended into EL1. Keep the SDK policy simple: + * capture a minimal register frame for diagnostics, then stop. + */ + .macro push_hyp_reg pc_adjust + mov r7, sp + sub sp, sp, #17 * 4 + stmia sp, {r0 - r12} + mov r0, sp + str r7, [r0, #13*4] + str lr, [r0, #14*4] + sub r6, lr, #\pc_adjust + str r6, [r0, #15*4] + mrs r6, spsr + str r6, [r0, #16*4] + .endm + +.globl SWI_Handler +SWI_Handler: + push_svc_reg 4 + bl rt_hw_trap_swi + b . + +.globl Undefined_Handler +Undefined_Handler: + push_svc_reg 4 + bl rt_hw_trap_undef + b . + +.globl SVC_Handler +SVC_Handler: + push_svc_reg 4 + b rt_hw_trap_svc + b . + +.globl Prefetch_Handler +Prefetch_Handler: + push_svc_reg 4 + b rt_hw_trap_pabt + b . + +.globl Abort_Handler +Abort_Handler: + push_svc_reg 8 + b rt_hw_trap_dabt + b . + +.globl Reserved_Handler +Reserved_Handler: + push_svc_reg 4 + b rt_hw_trap_resv + b . + +.globl FIQ_Handler +FIQ_Handler: + stmdb sp!, {r0-r12, lr} + +#ifdef RT_USING_FPU + vmrs r0, fpexc + tst r0, #0x40000000 + beq __no_vfp_frame_str_fiq + vstmdb sp!, {d0-d15} + vmrs r1, fpscr + stmdb sp!, {r1} +__no_vfp_frame_str_fiq: + stmdb sp!, {r0} +#endif + + bl rt_interrupt_enter + bl rt_hw_trap_fiq + bl rt_interrupt_leave + +#ifdef RT_USING_FPU + ldmia sp!, {r0} + vmsr fpexc, r0 + tst r0, #0x40000000 + beq __no_vfp_frame_ldr_fiq + ldmia sp!, {r1} + vmsr fpscr, r1 + vldmia sp!, {d0-d15} +__no_vfp_frame_ldr_fiq: +#endif + + ldmia sp!, {r0-r12, lr} + subs pc, lr, #4 + +.globl EL2_Undefined_Handler +EL2_Undefined_Handler: + push_hyp_reg 4 + mov r1, #0 + bl rt_hw_trap_el2 + b . + +.globl EL2_Prefetch_Handler +EL2_Prefetch_Handler: + push_hyp_reg 4 + mov r1, #1 + bl rt_hw_trap_el2 + b . + +.globl EL2_Abort_Handler +EL2_Abort_Handler: + push_hyp_reg 8 + mov r1, #2 + bl rt_hw_trap_el2 + b . + +.globl EL2_IRQ_Handler +EL2_IRQ_Handler: + push_hyp_reg 4 + mov r1, #3 + bl rt_hw_trap_el2 + b . + +.globl EL2_FIQ_Handler +EL2_FIQ_Handler: + push_hyp_reg 4 + mov r1, #4 + bl rt_hw_trap_el2 + b . + +.globl EL2_HVC_Handler +EL2_HVC_Handler: + push_hyp_reg 4 + mov r1, #5 + bl rt_hw_trap_el2 + b . + +.globl EL2_Trap_Handler +EL2_Trap_Handler: + push_hyp_reg 4 + mov r1, #6 + bl rt_hw_trap_el2 + b . From dde0bcdfe5c61f79ca4fa898fda597535b3d1b6c Mon Sep 17 00:00:00 2001 From: rcitach Date: Mon, 20 Apr 2026 12:22:44 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0CI=E7=9C=8B=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ALL_BSP_COMPILE.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/ALL_BSP_COMPILE.json b/.github/ALL_BSP_COMPILE.json index 9977e293f41..f49becceb68 100644 --- a/.github/ALL_BSP_COMPILE.json +++ b/.github/ALL_BSP_COMPILE.json @@ -518,6 +518,13 @@ "SUB_RTT_BSP": [ "allwinner/d1s" ] + }, + { + "RTT_BSP": "RDK", + "RTT_TOOL_CHAIN": "sourcery-arm", + "SUB_RTT_BSP": [ + "rdk/s100" + ] } ] } From 0756e351d04317b2206eaf6312bd86144a98a753 Mon Sep 17 00:00:00 2001 From: rcitach Date: Mon, 20 Apr 2026 12:23:42 +0000 Subject: [PATCH 3/6] =?UTF-8?q?formatting=20=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/rdk/s100/applications/main.c | 1 + bsp/rdk/s100/board/board.c | 1 + bsp/rdk/s100/board/board.h | 1 + bsp/rdk/s100/board/rsc_table.c | 89 +++++++++++++++--------------- bsp/rdk/s100/board/rsc_table.h | 67 +++++++++++----------- bsp/rdk/s100/drivers/drv_can.c | 10 +++- bsp/rdk/s100/drivers/drv_can.h | 3 +- bsp/rdk/s100/drivers/drv_gpio.c | 1 + bsp/rdk/s100/drivers/drv_gpio.h | 1 + bsp/rdk/s100/drivers/drv_pinmux.c | 1 + bsp/rdk/s100/drivers/drv_pinmux.h | 1 + bsp/rdk/s100/drivers/drv_timer.c | 1 + bsp/rdk/s100/drivers/drv_uart_v2.c | 12 ++-- bsp/rdk/s100/rtconfig.h | 1 + bsp/rdk/s100/startup/armv8.h | 3 +- bsp/rdk/s100/startup/backtrace.c | 8 ++- bsp/rdk/s100/startup/cp15.h | 3 +- bsp/rdk/s100/startup/cpuport.c | 3 +- bsp/rdk/s100/startup/cpuport.h | 27 ++++----- bsp/rdk/s100/startup/gicv3.c | 13 +++-- bsp/rdk/s100/startup/gicv3.h | 12 ++-- bsp/rdk/s100/startup/interrupt.c | 3 +- bsp/rdk/s100/startup/interrupt.h | 2 +- bsp/rdk/s100/startup/stack.c | 5 +- bsp/rdk/s100/startup/system.c | 1 + bsp/rdk/s100/startup/trap.c | 5 +- 26 files changed, 153 insertions(+), 122 deletions(-) diff --git a/bsp/rdk/s100/applications/main.c b/bsp/rdk/s100/applications/main.c index d7290af2fde..da5cc865e8f 100644 --- a/bsp/rdk/s100/applications/main.c +++ b/bsp/rdk/s100/applications/main.c @@ -14,3 +14,4 @@ int main(void) rt_kprintf("Hi, RT-Thread!\n"); return 0; } + diff --git a/bsp/rdk/s100/board/board.c b/bsp/rdk/s100/board/board.c index c88b3de5644..f98578f7d08 100644 --- a/bsp/rdk/s100/board/board.c +++ b/bsp/rdk/s100/board/board.c @@ -29,3 +29,4 @@ void rt_hw_board_init(void) rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif } + diff --git a/bsp/rdk/s100/board/board.h b/bsp/rdk/s100/board/board.h index 569e697f43c..b3df599ba04 100644 --- a/bsp/rdk/s100/board/board.h +++ b/bsp/rdk/s100/board/board.h @@ -96,3 +96,4 @@ rt_inline rt_uint32_t platform_get_gic_redist_base(void) #endif #endif + diff --git a/bsp/rdk/s100/board/rsc_table.c b/bsp/rdk/s100/board/rsc_table.c index 0a660c0269f..887f7b3fa88 100644 --- a/bsp/rdk/s100/board/rsc_table.c +++ b/bsp/rdk/s100/board/rsc_table.c @@ -13,61 +13,62 @@ extern uint32_t CAN_START_ADDR; extern uint32_t FLASH_SEC_ADDR; extern uint32_t FLASH_STARTUP_LEN; -#define NUM_TABLE_ENTRIES (7) -#define HB_SECTION_T(S) __attribute__((__section__(#S))) -#define HB_RESOURCE HB_SECTION_T(.resource_table) -#define MCU_FLASH_START_BASE_ADDR (0x0CAA5000) -#define MCU_FLASH_BASE_ADDR (0x0CAA5400) +#define NUM_TABLE_ENTRIES (7) +#define HB_SECTION_T(S) __attribute__((__section__(#S))) +#define HB_RESOURCE HB_SECTION_T(.resource_table) +#define MCU_FLASH_START_BASE_ADDR (0x0CAA5000) +#define MCU_FLASH_BASE_ADDR (0x0CAA5400) #define MCU_FREERTOS_HEAP_BASE_ADDR ((uint32_t)&OS_HEAP_START_ADDR) #define MCU_LOG_BASE_ADDR ((uint32_t)&MCU_LOG_START_ADDR) #define MCU_SCMI_BASE_ADDR ((uint32_t)&__SCMI_IPC_START_ADDR) -#define MCU_ATCM_ADDR ((uint32_t)&ATCM_START_ADDR) -#define MCU_FLASH_START_DDR_ADDR (0x0CAB0000) -#define MCU_FLASH_DDR_ADDR ((uint32_t)&FLASH_SEC_ADDR) +#define MCU_ATCM_ADDR ((uint32_t)&ATCM_START_ADDR) +#define MCU_FLASH_START_DDR_ADDR (0x0CAB0000) +#define MCU_FLASH_DDR_ADDR ((uint32_t)&FLASH_SEC_ADDR) #define MCU_FREERTOS_HEAP_DDR_ADDR ((uint32_t)&OS_HEAP_START_ADDR) #define MCU_LOG_DDR_ADDR ((uint32_t)&MCU_LOG_START_ADDR) #define MCU_SCMI_DDR_ADDR ((uint32_t)&__SCMI_IPC_START_ADDR) -#define MCU_BTCM_ADDR ((uint32_t)&CAN_START_ADDR) -#define MCU_FLASH_START_SIZE ((uint32_t)&FLASH_STARTUP_LEN) -#define MCU_FLASH_SIZE (0x2AAC00) +#define MCU_BTCM_ADDR ((uint32_t)&CAN_START_ADDR) +#define MCU_FLASH_START_SIZE ((uint32_t)&FLASH_STARTUP_LEN) +#define MCU_FLASH_SIZE (0x2AAC00) #define MCU_RTTHREAD_HEAP_ADDR ((uint32_t)&OS_HEAP_START_ADDR) -#define MCU_RTTHREAD_HEAP_SIZE ((uint32_t)&OS_HEAP_SIZE) -#define MCU_LOG_SIZE ((uint32_t)&MCU_LOG_SIZE) -#define MCU_SCMI_SIZE ((uint32_t)&__SCMI_IPC_SIZE) -#define MCU_ATCM_SIZE ((uint32_t)&ATCM_SIZE) +#define MCU_RTTHREAD_HEAP_SIZE ((uint32_t)&OS_HEAP_SIZE) +#define MCU_LOG_SIZE ((uint32_t)&MCU_LOG_SIZE) +#define MCU_SCMI_SIZE ((uint32_t)&__SCMI_IPC_SIZE) +#define MCU_ATCM_SIZE ((uint32_t)&ATCM_SIZE) const struct remote_resource_table HB_RESOURCE resources = { - /* Version */ - 1, + /* Version */ + 1, - /* NUmber of table entries */ - NUM_TABLE_ENTRIES, - /* reserved fields */ - {0x0, 0x0,}, + /* NUmber of table entries */ + NUM_TABLE_ENTRIES, + /* reserved fields */ + {0x0, 0x0,}, - /* Offsets of rsc entries */ - { - // offsetof(struct remote_resource_table, rproc_version), - // offsetof(struct remote_resource_table, fw_chksum), - // offsetof(struct remote_resource_table, ddr_devmem), - // offsetof(struct remote_resource_table, tcm_devmem), - // offsetof(struct remote_resource_table, rpmsg_vdev), - offsetof(struct remote_resource_table, fw_version), - offsetof(struct remote_resource_table, startup_devmem), - offsetof(struct remote_resource_table, flash_devmem), - offsetof(struct remote_resource_table, freertos_heap_devmem), - offsetof(struct remote_resource_table, log_devmem), - offsetof(struct remote_resource_table, scmi_devmem), - offsetof(struct remote_resource_table, atcm_devmem), - }, + /* Offsets of rsc entries */ + { + /* offsetof(struct remote_resource_table, rproc_version), */ + /* offsetof(struct remote_resource_table, fw_chksum), */ + /* offsetof(struct remote_resource_table, ddr_devmem), */ + /* offsetof(struct remote_resource_table, tcm_devmem), */ + /* offsetof(struct remote_resource_table, rpmsg_vdev), */ + offsetof(struct remote_resource_table, fw_version), + offsetof(struct remote_resource_table, startup_devmem), + offsetof(struct remote_resource_table, flash_devmem), + offsetof(struct remote_resource_table, freertos_heap_devmem), + offsetof(struct remote_resource_table, log_devmem), + offsetof(struct remote_resource_table, scmi_devmem), + offsetof(struct remote_resource_table, atcm_devmem), + }, - {(uint32_t)RSC_VERSION, {0}, {0}, {0}}, - /* flash_start_mem entry */ - {(uint32_t)RSC_DEVMEM, MCU_FLASH_START_DDR_ADDR, MCU_FLASH_START_DDR_ADDR, MCU_FLASH_START_SIZE, 0, 0, "startup devmem"}, - {(uint32_t)RSC_DEVMEM, MCU_FLASH_DDR_ADDR, MCU_FLASH_DDR_ADDR, MCU_FLASH_SIZE, 0, 0, "flash devmem"}, - {(uint32_t)RSC_DEVMEM, MCU_RTTHREAD_HEAP_ADDR, MCU_RTTHREAD_HEAP_ADDR, MCU_RTTHREAD_HEAP_SIZE, 0, 0, "rtthread_heap devmem"}, - {(uint32_t)RSC_DEVMEM, MCU_LOG_DDR_ADDR, MCU_LOG_DDR_ADDR, MCU_LOG_SIZE, 0, 0, "log devmem"}, - {(uint32_t)RSC_DEVMEM, MCU_SCMI_DDR_ADDR, MCU_SCMI_DDR_ADDR, MCU_SCMI_SIZE, 0, 0, "scmi devmem"}, - {(uint32_t)RSC_DEVMEM, MCU_ATCM_ADDR, MCU_BTCM_ADDR, MCU_ATCM_SIZE, 0, 0, "atcm devmem"}, + {(uint32_t)RSC_VERSION, {0}, {0}, {0}}, + /* flash_start_mem entry */ + {(uint32_t)RSC_DEVMEM, MCU_FLASH_START_DDR_ADDR, MCU_FLASH_START_DDR_ADDR, MCU_FLASH_START_SIZE, 0, 0, "startup devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_FLASH_DDR_ADDR, MCU_FLASH_DDR_ADDR, MCU_FLASH_SIZE, 0, 0, "flash devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_RTTHREAD_HEAP_ADDR, MCU_RTTHREAD_HEAP_ADDR, MCU_RTTHREAD_HEAP_SIZE, 0, 0, "rtthread_heap devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_LOG_DDR_ADDR, MCU_LOG_DDR_ADDR, MCU_LOG_SIZE, 0, 0, "log devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_SCMI_DDR_ADDR, MCU_SCMI_DDR_ADDR, MCU_SCMI_SIZE, 0, 0, "scmi devmem"}, + {(uint32_t)RSC_DEVMEM, MCU_ATCM_ADDR, MCU_BTCM_ADDR, MCU_ATCM_SIZE, 0, 0, "atcm devmem"}, }; + diff --git a/bsp/rdk/s100/board/rsc_table.h b/bsp/rdk/s100/board/rsc_table.h index a0a447da629..9306f26715e 100644 --- a/bsp/rdk/s100/board/rsc_table.h +++ b/bsp/rdk/s100/board/rsc_table.h @@ -33,57 +33,58 @@ * for use by the Linux Master */ #ifndef HB_RSC_TABLE_H #define HB_RSC_TABLE_H - + #include #include struct fw_rsc_version_with_type { - uint32_t typefw_rsc_version; - uint8_t version[48]; - uint8_t compile_time[16]; - uint8_t git_hash_id[40]; + uint32_t typefw_rsc_version; + uint8_t version[48]; + uint8_t compile_time[16]; + uint8_t git_hash_id[40]; }; enum fw_resource_type { - RSC_CARVEOUT = 0, - RSC_DEVMEM = 1, - RSC_TRACE = 2, - RSC_VDEV = 3, - RSC_RPROC_MEM = 4U, - RSC_FW_CHKSUM = 5U, - RSC_VERSION = 6U, - RSC_LAST = 7U, - RSC_VENDOR_START = 128, - RSC_VENDOR_END = 512, + RSC_CARVEOUT = 0, + RSC_DEVMEM = 1, + RSC_TRACE = 2, + RSC_VDEV = 3, + RSC_RPROC_MEM = 4U, + RSC_FW_CHKSUM = 5U, + RSC_VERSION = 6U, + RSC_LAST = 7U, + RSC_VENDOR_START = 128, + RSC_VENDOR_END = 512, }; struct fw_rsc_devmem_with_type { - uint32_t typefw_rsc_devmem; - uint32_t da; - uint32_t pa; - uint32_t len; - uint32_t flags; - uint32_t reserved; - uint8_t name[32]; + uint32_t typefw_rsc_devmem; + uint32_t da; + uint32_t pa; + uint32_t len; + uint32_t flags; + uint32_t reserved; + uint8_t name[32]; }; #define NO_RESOURCE_ENTRIES (7U) /* Resource table for the given remote */ struct remote_resource_table { - uint32_t version; - uint32_t num; - uint32_t reserved[2]; - uint32_t offset[NO_RESOURCE_ENTRIES]; - struct fw_rsc_version_with_type fw_version; /*PRQA S ALL*/ - struct fw_rsc_devmem_with_type startup_devmem; - struct fw_rsc_devmem_with_type flash_devmem; - struct fw_rsc_devmem_with_type freertos_heap_devmem; - struct fw_rsc_devmem_with_type log_devmem; - struct fw_rsc_devmem_with_type scmi_devmem; - struct fw_rsc_devmem_with_type atcm_devmem; + uint32_t version; + uint32_t num; + uint32_t reserved[2]; + uint32_t offset[NO_RESOURCE_ENTRIES]; + struct fw_rsc_version_with_type fw_version; /*PRQA S ALL*/ + struct fw_rsc_devmem_with_type startup_devmem; + struct fw_rsc_devmem_with_type flash_devmem; + struct fw_rsc_devmem_with_type freertos_heap_devmem; + struct fw_rsc_devmem_with_type log_devmem; + struct fw_rsc_devmem_with_type scmi_devmem; + struct fw_rsc_devmem_with_type atcm_devmem; }__attribute__((packed, aligned(0x100))); extern const struct remote_resource_table resources; #endif /* RSC_TABLE_H_ */ + diff --git a/bsp/rdk/s100/drivers/drv_can.c b/bsp/rdk/s100/drivers/drv_can.c index 86856edc9c7..6edefb608c0 100644 --- a/bsp/rdk/s100/drivers/drv_can.c +++ b/bsp/rdk/s100/drivers/drv_can.c @@ -318,6 +318,7 @@ static rt_uint32_t s100_can_basic_build_mb_cs(rt_uint32_t code, rt_uint32_t dlc, { cs |= (1UL << 21) | (1UL << 22); } + if (rtr != RT_FALSE) { cs |= (1UL << 20); @@ -437,6 +438,7 @@ static void s100_can_basic_update_irq_mask(struct s100_can_basic *ctrl, rt_uint3 { imask1_tx |= (1UL << i); } + for (i = 0U; i < (S100_CAN_MAX_MB_INDEX - 32U); i++) { imask2_tx |= (1UL << i); @@ -974,7 +976,7 @@ static rt_err_t s100_can_basic_configure(struct rt_can_device *can, struct can_c CAN_RET(-RT_EINVAL, "configure invalid sndboxnumber=0"); } - //TODO legacy RXFIFO 0-S100_CAN_MAX_MB_INDEX + /* TODO legacy RXFIFO 0-S100_CAN_MAX_MB_INDEX */ if (cfg->sndboxnumber > S100_CAN_MAX_MB_INDEX - S100_CAN_BASIC_TX_MB_START) { CAN_RET_FMT(-RT_EINVAL, "configure sndboxnumber too large=%lu", @@ -1048,6 +1050,7 @@ static rt_err_t s100_can_basic_control(struct rt_can_device *can, int cmd, void { can->config.baud_rate = new_baud; } + if (ret != RT_EOK) { CAN_RET_FMT(ret, "control set baud failed ctrl=%s baud=%lu", @@ -1066,6 +1069,7 @@ static rt_err_t s100_can_basic_control(struct rt_can_device *can, int cmd, void { can->config.mode = new_mode; } + if (ret != RT_EOK) { CAN_RET_FMT(ret, "control set mode failed ctrl=%s mode=%lu", @@ -1148,6 +1152,7 @@ static rt_ssize_t s100_can_basic_sendmsg_nonblocking(struct rt_can_device *can, { return RT_EOK; } + if (ret != -RT_EBUSY) { CAN_RET_FMT(ret, "sendmsg nonblocking failed boxno=%lu", (unsigned long)boxno); @@ -1283,7 +1288,7 @@ int rt_hw_can_init(void) s100_can_board_enable_transceiver(); for (i = 0U; i < (sizeof(s100_can_basics) / sizeof(s100_can_basics[0])); i++) - { + { s100_can_basics[i].can_dev.config = cfg; s100_can_basics[i].can_dev.parent.user_data = &s100_can_basics[i]; @@ -1311,3 +1316,4 @@ int rt_hw_can_init(void) return RT_EOK; } INIT_DEVICE_EXPORT(rt_hw_can_init); + diff --git a/bsp/rdk/s100/drivers/drv_can.h b/bsp/rdk/s100/drivers/drv_can.h index 68febe573db..2697599b647 100644 --- a/bsp/rdk/s100/drivers/drv_can.h +++ b/bsp/rdk/s100/drivers/drv_can.h @@ -237,7 +237,7 @@ typedef struct #define FLEXCAN_CTRL1_SMP_WIDTH (1U) #define FLEXCAN_CTRL1_SMP(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_SMP_SHIFT)) & FLEXCAN_CTRL1_SMP_MASK) -#define FLEXCAN_CTRL1_CLKSRC_MASK (0x2000U)//zjh add +#define FLEXCAN_CTRL1_CLKSRC_MASK (0x2000U)/* zjh add */ #define FLEXCAN_CTRL1_CLKSRC_SHIFT (13U) #define FLEXCAN_CTRL1_CLKSRC(x) (((rt_uint32_t)(((rt_uint32_t)(x)) << FLEXCAN_CTRL1_CLKSRC_SHIFT)) & FLEXCAN_CTRL1_CLKSRC_MASK) @@ -1221,3 +1221,4 @@ typedef struct #define FLEXCAN_IP_FEATURE_EXPANDABLE_MEMORY_NUM (6U) #endif + diff --git a/bsp/rdk/s100/drivers/drv_gpio.c b/bsp/rdk/s100/drivers/drv_gpio.c index 6109e67d0d4..17863fbfb90 100644 --- a/bsp/rdk/s100/drivers/drv_gpio.c +++ b/bsp/rdk/s100/drivers/drv_gpio.c @@ -492,3 +492,4 @@ int rt_hw_pin_init(void) return rt_device_pin_register("pin", &s100_pin_ops, RT_NULL); } INIT_DEVICE_EXPORT(rt_hw_pin_init); + diff --git a/bsp/rdk/s100/drivers/drv_gpio.h b/bsp/rdk/s100/drivers/drv_gpio.h index e60900dacdd..ee6464129b1 100644 --- a/bsp/rdk/s100/drivers/drv_gpio.h +++ b/bsp/rdk/s100/drivers/drv_gpio.h @@ -28,3 +28,4 @@ void s100_gpio_write(rt_uint8_t pin, rt_uint8_t value); rt_uint8_t s100_gpio_read(rt_uint8_t pin); #endif + diff --git a/bsp/rdk/s100/drivers/drv_pinmux.c b/bsp/rdk/s100/drivers/drv_pinmux.c index 70916629a7d..c9de85cde0d 100644 --- a/bsp/rdk/s100/drivers/drv_pinmux.c +++ b/bsp/rdk/s100/drivers/drv_pinmux.c @@ -145,3 +145,4 @@ rt_err_t s100_pin_set_pull(s100_pin_t pin, s100_pin_pull_t pull) s100_pin_cfg_regs[pin].value = cfg.value; return RT_EOK; } + diff --git a/bsp/rdk/s100/drivers/drv_pinmux.h b/bsp/rdk/s100/drivers/drv_pinmux.h index b1369193f3e..e3dc3cd79ac 100644 --- a/bsp/rdk/s100/drivers/drv_pinmux.h +++ b/bsp/rdk/s100/drivers/drv_pinmux.h @@ -35,3 +35,4 @@ rt_err_t s100_pin_set_function(s100_pin_t pin, s100_pin_function_t function); rt_err_t s100_pin_set_pull(s100_pin_t pin, s100_pin_pull_t pull); #endif + diff --git a/bsp/rdk/s100/drivers/drv_timer.c b/bsp/rdk/s100/drivers/drv_timer.c index 90572fa77ed..94b3ab4e786 100644 --- a/bsp/rdk/s100/drivers/drv_timer.c +++ b/bsp/rdk/s100/drivers/drv_timer.c @@ -90,3 +90,4 @@ int rt_hw_timer_init(void) return 0; } INIT_BOARD_EXPORT(rt_hw_timer_init); + diff --git a/bsp/rdk/s100/drivers/drv_uart_v2.c b/bsp/rdk/s100/drivers/drv_uart_v2.c index 50d236889af..d20643495a1 100644 --- a/bsp/rdk/s100/drivers/drv_uart_v2.c +++ b/bsp/rdk/s100/drivers/drv_uart_v2.c @@ -60,10 +60,10 @@ /* * These are the definitions for the Interrupt Enable Register */ -#define UART_IER_MSI (0x08U) /**< Enable Modem status interrupt */ -#define UART_IER_RLSI (0x04U) /**< Enable receiver line status interrupt */ -#define UART_IER_THRI (0x02U) /**< Enable Transmitter holding register int. */ -#define UART_IER_RDI (0x01U) /**< Enable receiver data interrupt */ +#define UART_IER_MSI (0x08U) /**< Enable Modem status interrupt */ +#define UART_IER_RLSI (0x04U) /**< Enable receiver line status interrupt */ +#define UART_IER_THRI (0x02U) /**< Enable Transmitter holding register int. */ +#define UART_IER_RDI (0x01U) /**< Enable receiver data interrupt */ #define UART4_IRQn (45) #define UART5_IRQn (46) @@ -206,6 +206,7 @@ static void s100_uart_isr(int vector, void *param) { return; } + switch (iir & UART_IIR_ID) { case UART_IIR_RDI: @@ -431,7 +432,7 @@ static rt_err_t s100_uart_control(struct rt_serial_device *serial, int cmd, void static int s100_uart_putc(struct rt_serial_device *serial, char c) { - + struct s100_uart *uart; RT_ASSERT(serial != RT_NULL); @@ -520,3 +521,4 @@ int rt_hw_uart_init(void) } INIT_BOARD_EXPORT(rt_hw_uart_init); #endif /* RT_USING_SERIAL_V2 */ + diff --git a/bsp/rdk/s100/rtconfig.h b/bsp/rdk/s100/rtconfig.h index 0cebd660dcc..310ad5ae4d4 100644 --- a/bsp/rdk/s100/rtconfig.h +++ b/bsp/rdk/s100/rtconfig.h @@ -426,3 +426,4 @@ /* end of Onboard Peripheral Drivers */ #endif + diff --git a/bsp/rdk/s100/startup/armv8.h b/bsp/rdk/s100/startup/armv8.h index 797223ed35e..636ab17aa6b 100644 --- a/bsp/rdk/s100/startup/armv8.h +++ b/bsp/rdk/s100/startup/armv8.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -78,3 +78,4 @@ struct rt_hw_stack void rt_hw_show_register(struct rt_hw_exp_stack *regs); #endif + diff --git a/bsp/rdk/s100/startup/backtrace.c b/bsp/rdk/s100/startup/backtrace.c index 85a693569d8..10a4b482db4 100644 --- a/bsp/rdk/s100/startup/backtrace.c +++ b/bsp/rdk/s100/startup/backtrace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -235,6 +235,7 @@ static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl, mask >>= 1; reg++; } + if (!load_sp) ctrl->vrs[SP] = (unsigned long)vsp; @@ -501,7 +502,7 @@ void unwind_backtrace(struct pt_regs *regs, const struct unwind_idx exidx_start[ urc = unwind_frame(&frame, &origin_idx, exidx_start, exidx_end); if (urc < 0) break; - //dump_backtrace_entry(where, frame.pc, frame.sp - 4); + /* dump_backtrace_entry(where, frame.pc, frame.sp - 4); */ #ifndef RT_BACKTRACE_FUNCTION_NAME rt_kprintf(" %08x", frame.pc); #endif @@ -542,4 +543,5 @@ rt_err_t rt_backtrace(void) rt_unwind(®s, 8); return RT_EOK; } -#endif // (__ICCARM__) undefined +#endif /* (__ICCARM__) undefined */ + diff --git a/bsp/rdk/s100/startup/cp15.h b/bsp/rdk/s100/startup/cp15.h index 0482ac31b6b..3742fdc4d7b 100644 --- a/bsp/rdk/s100/startup/cp15.h +++ b/bsp/rdk/s100/startup/cp15.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2024, Shanghai Real-Thread Electronic Technology Co.,Ltd + * Copyright (c) 2011-2026, Shanghai Real-Thread Electronic Technology Co.,Ltd * * Change Logs: * Date Author Notes @@ -27,3 +27,4 @@ __asm volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) #endif + diff --git a/bsp/rdk/s100/startup/cpuport.c b/bsp/rdk/s100/startup/cpuport.c index 5fce3d051a1..15a258cb64c 100644 --- a/bsp/rdk/s100/startup/cpuport.c +++ b/bsp/rdk/s100/startup/cpuport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2024, Shanghai Real-Thread Electronic Technology Co.,Ltd + * Copyright (c) 2011-2026, Shanghai Real-Thread Electronic Technology Co.,Ltd * * Change Logs: * Date Author Notes @@ -56,3 +56,4 @@ void rt_hw_cpu_shutdown() } /*@}*/ + diff --git a/bsp/rdk/s100/startup/cpuport.h b/bsp/rdk/s100/startup/cpuport.h index 8b408e054cf..4f132e0e1d0 100644 --- a/bsp/rdk/s100/startup/cpuport.h +++ b/bsp/rdk/s100/startup/cpuport.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2024, Shanghai Real-Thread Electronic Technology Co.,Ltd + * Copyright (c) 2011-2026, Shanghai Real-Thread Electronic Technology Co.,Ltd * * Change Logs: * Date Author Notes @@ -71,19 +71,20 @@ struct rt_hw_stack #define J_Bit (1<<24) -// rt_inline void rt_hw_isb(void) -// { -// __asm volatile ("isb":::"memory"); -// } +/* rt_inline void rt_hw_isb(void) */ +/* { */ +/* __asm volatile ("isb":::"memory"); */ +/* } */ -// rt_inline void rt_hw_dmb(void) -// { -// __asm volatile ("dmb":::"memory"); -// } +/* rt_inline void rt_hw_dmb(void) */ +/* { */ +/* __asm volatile ("dmb":::"memory"); */ +/* } */ -// rt_inline void rt_hw_dsb(void) -// { -// __asm volatile ("dsb":::"memory"); -// } +/* rt_inline void rt_hw_dsb(void) */ +/* { */ +/* __asm volatile ("dsb":::"memory"); */ +/* } */ #endif /*CPUPORT_H__*/ + diff --git a/bsp/rdk/s100/startup/gicv3.c b/bsp/rdk/s100/startup/gicv3.c index e1d71450612..c774ec02f69 100644 --- a/bsp/rdk/s100/startup/gicv3.c +++ b/bsp/rdk/s100/startup/gicv3.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -425,8 +425,8 @@ void arm_gic_set_system_register_enable_mask(rt_uint32_t index, rt_uint32_t valu /* set priority mask */ __set_gicv3_reg(ICC_SRE, value); __ISB(); -// __asm volatile ("isb 0xF":: -// :"memory"); +/* __asm volatile ("isb 0xF":: */ +/* :"memory"); */ } rt_uint32_t arm_gic_get_system_register_enable_mask(rt_uint32_t index) @@ -682,9 +682,9 @@ int arm_gic_redist_init(rt_uint32_t index) base = _gic_table[index].redist_hw_base[cpu_id]; /* redistributor enable */ - // 将原来的值的第二位清零,其他位保持不变 + /* 将原来的值的第二位清零,其他位保持不变 */ GIC_RDIST_WAKER(base) &= ~(1U << 1); - // 一直执行,直到GIC_RDIST_WAKER(base)的值的第2位(从0开始计数)为0 + /* 一直执行,直到GIC_RDIST_WAKER(base)的值的第2位(从0开始计数)为0 */ while (GIC_RDIST_WAKER(base) & (1 << 2)) { ; @@ -708,7 +708,7 @@ int arm_gic_redist_init(rt_uint32_t index) } /* Trigger level for PPI interrupts*/ - GIC_RDISTSGI_ICFGR1(base) = 0x0U; // PPI is level-sensitive. + GIC_RDISTSGI_ICFGR1(base) = 0x0U; /* PPI is level-sensitive. */ return 0; } @@ -828,3 +828,4 @@ long gic_dump(void) return 0; } + diff --git a/bsp/rdk/s100/startup/gicv3.h b/bsp/rdk/s100/startup/gicv3.h index e92c6cd9f7f..3a7bf3d7418 100644 --- a/bsp/rdk/s100/startup/gicv3.h +++ b/bsp/rdk/s100/startup/gicv3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -54,12 +54,12 @@ */ #define GICD_CTLR_RWP ((unsigned int)1<<31) #define GICD_CTLR_E1NWF (1<<7) -#define GICD_CTLR_DS (1<<6) // 当两种安全模式被同时支持时,可以通过GICD_CTLR.DS==1关闭其中一个,只支持non-secure模式 +#define GICD_CTLR_DS (1<<6) /* 当两种安全模式被同时支持时,可以通过GICD_CTLR.DS==1关闭其中一个,只支持non-secure模式 */ #define GICD_CTLR_ARE_NS (1<<5) #define GICD_CTLR_ARE_S (1<<4) -#define GICD_CTLR_ENGRP1S (1<<2) // secure group 1 -#define GICD_CTLR_ENGRP1NS (1<<1) // non-secure group 1 -#define GICD_CTLR_ENGRP0 (1<<0) // group 0 +#define GICD_CTLR_ENGRP1S (1<<2) /* secure group 1 */ +#define GICD_CTLR_ENGRP1NS (1<<1) /* non-secure group 1 */ +#define GICD_CTLR_ENGRP0 (1<<0) /* group 0 */ /** Macro to access the Redistributor Control Register (GICR_CTLR) */ @@ -133,7 +133,7 @@ #define GIC_RDISTSGI_ICFGR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U) #define GIC_RDISTSGI_ICFGR1(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U) #define GIC_RDISTSGI_IGRPMODR0(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n)*4) -#define GIC_RDISTSGI_NSACR(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) // 当执行一个非安全模式到安全模式的访问 +#define GIC_RDISTSGI_NSACR(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) /* 当执行一个非安全模式到安全模式的访问 */ #define GIC_RSGI_AFF1_OFFSET 16 #define GIC_RSGI_AFF2_OFFSET 32 diff --git a/bsp/rdk/s100/startup/interrupt.c b/bsp/rdk/s100/startup/interrupt.c index 3306e4f9651..9ad71725ef8 100644 --- a/bsp/rdk/s100/startup/interrupt.c +++ b/bsp/rdk/s100/startup/interrupt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -279,3 +279,4 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, return old_handler; } + diff --git a/bsp/rdk/s100/startup/interrupt.h b/bsp/rdk/s100/startup/interrupt.h index 804943ea96f..db38f7b8d36 100644 --- a/bsp/rdk/s100/startup/interrupt.h +++ b/bsp/rdk/s100/startup/interrupt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/bsp/rdk/s100/startup/stack.c b/bsp/rdk/s100/startup/stack.c index e60ab891ac9..79f9958d302 100644 --- a/bsp/rdk/s100/startup/stack.c +++ b/bsp/rdk/s100/startup/stack.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2024, Shanghai Real-Thread Electronic Technology Co.,Ltd + * Copyright (c) 2011-2026, Shanghai Real-Thread Electronic Technology Co.,Ltd * * Change Logs: * Date Author Notes @@ -8,7 +8,7 @@ #include "armv8.h" #include -//#include +/* #include */ /** * This function will initialize thread stack @@ -69,3 +69,4 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, } /*@}*/ + diff --git a/bsp/rdk/s100/startup/system.c b/bsp/rdk/s100/startup/system.c index f32988df5f9..f8c1442656f 100644 --- a/bsp/rdk/s100/startup/system.c +++ b/bsp/rdk/s100/startup/system.c @@ -133,3 +133,4 @@ rt_bool_t s100_board_irq_is_supported(int irq) return RT_FALSE; } + diff --git a/bsp/rdk/s100/startup/trap.c b/bsp/rdk/s100/startup/trap.c index 39bb2bece6c..45f2b35baf5 100644 --- a/bsp/rdk/s100/startup/trap.c +++ b/bsp/rdk/s100/startup/trap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -12,7 +12,7 @@ #include #include #include -//#include +/* #include */ #include "interrupt.h" @@ -340,3 +340,4 @@ void rt_hw_trap_fiq(void) /* end of interrupt */ rt_hw_interrupt_ack(ir); } + From 97ec22473c1611e6e7bd42eca13a185ccf7d8ff9 Mon Sep 17 00:00:00 2001 From: rcitach Date: Tue, 21 Apr 2026 17:15:26 +0000 Subject: [PATCH 4/6] =?UTF-8?q?=E5=A4=8D=E7=94=A8=20libcpu=20=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/rdk/s100/SConstruct | 48 +- bsp/rdk/s100/board/board.h | 8 + bsp/rdk/s100/startup/SConscript | 2 +- bsp/rdk/s100/startup/armv8.h | 81 --- bsp/rdk/s100/startup/backtrace.c | 547 ------------------ bsp/rdk/s100/startup/backtrace.h | 83 --- bsp/rdk/s100/startup/cp15.h | 30 - bsp/rdk/s100/startup/cp15_gcc.S | 167 ------ bsp/rdk/s100/startup/cpuport.c | 59 -- bsp/rdk/s100/startup/cpuport.h | 90 --- bsp/rdk/s100/startup/gicv3.h | 197 ------- bsp/rdk/s100/startup/interrupt.h | 54 -- .../startup/{startup_gcc.S => start_gcc.S} | 0 bsp/rdk/s100/startup/trap.c | 343 ----------- bsp/rdk/s100/startup/vector_gcc.S | 76 +-- 15 files changed, 85 insertions(+), 1700 deletions(-) delete mode 100644 bsp/rdk/s100/startup/armv8.h delete mode 100644 bsp/rdk/s100/startup/backtrace.c delete mode 100644 bsp/rdk/s100/startup/backtrace.h delete mode 100644 bsp/rdk/s100/startup/cp15.h delete mode 100644 bsp/rdk/s100/startup/cp15_gcc.S delete mode 100644 bsp/rdk/s100/startup/cpuport.c delete mode 100644 bsp/rdk/s100/startup/cpuport.h delete mode 100644 bsp/rdk/s100/startup/gicv3.h delete mode 100644 bsp/rdk/s100/startup/interrupt.h rename bsp/rdk/s100/startup/{startup_gcc.S => start_gcc.S} (100%) delete mode 100644 bsp/rdk/s100/startup/trap.c diff --git a/bsp/rdk/s100/SConstruct b/bsp/rdk/s100/SConstruct index 2a674084ce5..022424e43ad 100644 --- a/bsp/rdk/s100/SConstruct +++ b/bsp/rdk/s100/SConstruct @@ -26,7 +26,53 @@ Export('RTT_ROOT') Export('rtconfig') # prepare building environment -objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True) +objs = PrepareBuilding(env, RTT_ROOT) + +def _replace_cortex_r52_with_startup(objects): + startup_dir = os.path.join(Dir('#').abspath, 'startup') + startup_names = set( + name for name in os.listdir(startup_dir) + if os.path.isfile(os.path.join(startup_dir, name)) + ) + cpu_dir = os.path.abspath(os.path.join(RTT_ROOT, 'libcpu', 'arm', 'cortex-r52')) + + def _source_path(node): + for attr in ('srcnode', 'rfile'): + if hasattr(node, attr): + source = getattr(node, attr)() + if hasattr(source, 'abspath'): + return os.path.abspath(source.abspath) + if hasattr(node, 'abspath'): + return os.path.abspath(node.abspath) + return None + + def _filter(items): + filtered = [] + for item in items: + if isinstance(item, list): + filtered.append(_filter(item)) + continue + + if not hasattr(item, 'abspath'): + filtered.append(item) + continue + + item_path = _source_path(item) + if item_path is None: + filtered.append(item) + continue + + item_name = os.path.basename(item_path) + if item_name in startup_names and item_path.startswith(cpu_dir + os.sep): + continue + + filtered.append(item) + + return filtered + + return _filter(objects) + +objs = _replace_cortex_r52_with_startup(objs) # make a building DoBuilding(TARGET, objs) diff --git a/bsp/rdk/s100/board/board.h b/bsp/rdk/s100/board/board.h index b3df599ba04..0b2965a2820 100644 --- a/bsp/rdk/s100/board/board.h +++ b/bsp/rdk/s100/board/board.h @@ -18,6 +18,14 @@ extern char OS_HEAP_END_ADDR; #error "GCC support only!" #endif +#ifndef __DSB +#define __DSB() __asm volatile ("dsb" : : : "memory") +#endif + +#ifndef __ISB +#define __ISB() __asm volatile ("isb" : : : "memory") +#endif + /*********************************************************************************************************************** * GIC definitions **********************************************************************************************************************/ diff --git a/bsp/rdk/s100/startup/SConscript b/bsp/rdk/s100/startup/SConscript index fd22e5e7612..d9b4ed776c0 100644 --- a/bsp/rdk/s100/startup/SConscript +++ b/bsp/rdk/s100/startup/SConscript @@ -8,6 +8,6 @@ cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.S') CPPPATH = [cwd] -group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('startup', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/bsp/rdk/s100/startup/armv8.h b/bsp/rdk/s100/startup/armv8.h deleted file mode 100644 index 636ab17aa6b..00000000000 --- a/bsp/rdk/s100/startup/armv8.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2006-2026, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __ARMV8_H__ -#define __ARMV8_H__ - -/* the exception stack without VFP registers */ -struct rt_hw_exp_stack -{ - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long sp; - unsigned long lr; - unsigned long pc; - unsigned long cpsr; -}; - -struct rt_hw_stack -{ - unsigned long cpsr; - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long lr; - unsigned long pc; -}; - -#define USERMODE 0x10 -#define FIQMODE 0x11 -#define IRQMODE 0x12 -#define SVCMODE 0x13 -#define MONITORMODE 0x16 -#define ABORTMODE 0x17 -#define HYPMODE 0x1b -#define UNDEFMODE 0x1b -#define MODEMASK 0x1f -#define NOINT 0xc0 - -#define T_Bit (1<<5) -#define F_Bit (1<<6) -#define I_Bit (1<<7) -#define A_Bit (1<<8) -#define E_Bit (1<<9) -#define J_Bit (1<<24) - -#define PABT_EXCEPTION 0x1 -#define DABT_EXCEPTION 0x2 -#define UND_EXCEPTION 0x3 -#define SWI_EXCEPTION 0x4 -#define RESV_EXCEPTION 0xF - -void rt_hw_show_register(struct rt_hw_exp_stack *regs); - -#endif - diff --git a/bsp/rdk/s100/startup/backtrace.c b/bsp/rdk/s100/startup/backtrace.c deleted file mode 100644 index 10a4b482db4..00000000000 --- a/bsp/rdk/s100/startup/backtrace.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright (c) 2006-2026, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-03-29 Jesven the first version - */ - -#ifndef __ICCARM__ -#ifndef __CHECKER__ -#if !defined (__ARM_EABI__) -#warning Your compiler does not have EABI support. -#warning ARM unwind is known to compile only with EABI compilers. -#warning Change compiler or disable ARM_UNWIND option. -#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2) && !defined(__clang__) -#warning Your compiler is too buggy; it is known to not compile ARM unwind support. -#warning Change compiler or disable ARM_UNWIND option. -#endif -#endif /* __CHECKER__ */ - -#include -#include -#include - -#define DBG_TAG "BACKTRACE" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_USING_SMART -#include -#include -#include -#endif - -rt_inline void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame) -{ - frame->fp = frame_pointer(regs); - frame->sp = regs->ARM_sp; - frame->lr = regs->ARM_lr; - frame->pc = regs->ARM_pc; -} - -struct unwind_ctrl_block { - unsigned long vrs[16]; /* virtual register set */ - const unsigned long *insn; /* pointer to the current instructions word */ - unsigned long sp_high; /* highest value of sp allowed */ - /* - * 1 : check for stack overflow for each register pop. - * 0 : save overhead if there is plenty of stack remaining. - */ - int check_each_pop; - int entries; /* number of entries left to interpret */ - int byte; /* current byte number in the instructions word */ -}; - -enum regs -{ -#ifdef CONFIG_THUMB2_KERNEL - FP = 7, -#else - FP = 11, -#endif - SP = 13, - LR = 14, - PC = 15 -}; - -static int core_kernel_text(unsigned long addr) -{ - return 1; -} - -/* Convert a prel31 symbol to an absolute address */ -#define prel31_to_addr(ptr) \ - ({ \ - /* sign-extend to 32 bits */ \ - long offset = (((long)*(ptr)) << 1) >> 1; \ - (unsigned long)(ptr) + offset; \ - }) - -/* - * Binary search in the unwind index. The entries are - * guaranteed to be sorted in ascending order by the linker. - * - * start = first entry - * origin = first entry with positive offset (or stop if there is no such entry) - * stop - 1 = last entry - */ -static const struct unwind_idx *search_index(unsigned long addr, - const struct unwind_idx *start, - const struct unwind_idx *origin, - const struct unwind_idx *stop) -{ - unsigned long addr_prel31; - - LOG_D("%s(%08lx, %x, %x, %x)", - __func__, addr, start, origin, stop); - - /* - * only search in the section with the matching sign. This way the - * prel31 numbers can be compared as unsigned longs. - */ - if (addr < (unsigned long)start) - /* negative offsets: [start; origin) */ - stop = origin; - else - /* positive offsets: [origin; stop) */ - start = origin; - - /* prel31 for address relavive to start */ - addr_prel31 = (addr - (unsigned long)start) & 0x7fffffff; - - while (start < stop - 1) - { - const struct unwind_idx *mid = start + ((stop - start) >> 1); - - /* - * As addr_prel31 is relative to start an offset is needed to - * make it relative to mid. - */ - if (addr_prel31 - ((unsigned long)mid - (unsigned long)start) < - mid->addr_offset) - stop = mid; - else - { - /* keep addr_prel31 relative to start */ - addr_prel31 -= ((unsigned long)mid - - (unsigned long)start); - start = mid; - } - } - - if (start->addr_offset <= addr_prel31) - return start; - else - { - LOG_W("unwind: Unknown symbol address %08lx", addr); - return RT_NULL; - } -} - -static const struct unwind_idx *unwind_find_origin( - const struct unwind_idx *start, const struct unwind_idx *stop) -{ - LOG_D("%s(%x, %x)", __func__, start, stop); - while (start < stop) - { - const struct unwind_idx *mid = start + ((stop - start) >> 1); - - if (mid->addr_offset >= 0x40000000) - /* negative offset */ - start = mid + 1; - else - /* positive offset */ - stop = mid; - } - LOG_D("%s -> %x", __func__, stop); - return stop; -} - -static const struct unwind_idx *unwind_find_idx(unsigned long addr, const struct unwind_idx **origin_idx, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]) -{ - const struct unwind_idx *idx = RT_NULL; - - LOG_D("%s(%08lx)", __func__, addr); - - if (core_kernel_text(addr)) - { - if (!*origin_idx) - *origin_idx = - unwind_find_origin(exidx_start, - exidx_end); - - /* main unwind table */ - idx = search_index(addr, exidx_start, - *origin_idx, - exidx_end); - } - - LOG_D("%s: idx = %x", __func__, idx); - return idx; -} - -static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl) -{ - unsigned long ret; - - if (ctrl->entries <= 0) - { - LOG_W("unwind: Corrupt unwind table"); - return 0; - } - - ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff; - - if (ctrl->byte == 0) - { - ctrl->insn++; - ctrl->entries--; - ctrl->byte = 3; - } - else - ctrl->byte--; - - return ret; -} - -/* Before poping a register check whether it is feasible or not */ -static int unwind_pop_register(struct unwind_ctrl_block *ctrl, - unsigned long **vsp, unsigned int reg) -{ - if (ctrl->check_each_pop) - if (*vsp >= (unsigned long *)ctrl->sp_high) - return -URC_FAILURE; - - ctrl->vrs[reg] = *(*vsp)++; - return URC_OK; -} - -/* Helper functions to execute the instructions */ -static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl, - unsigned long mask) -{ - unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; - int load_sp, reg = 4; - - load_sp = mask & (1 << (13 - 4)); - while (mask) - { - if (mask & 1) - if (unwind_pop_register(ctrl, &vsp, reg)) - return -URC_FAILURE; - mask >>= 1; - reg++; - } - - if (!load_sp) - ctrl->vrs[SP] = (unsigned long)vsp; - - return URC_OK; -} - -static int unwind_exec_pop_r4_to_rN(struct unwind_ctrl_block *ctrl, - unsigned long insn) -{ - unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; - int reg; - - /* pop R4-R[4+bbb] */ - for (reg = 4; reg <= 4 + (insn & 7); reg++) - if (unwind_pop_register(ctrl, &vsp, reg)) - return -URC_FAILURE; - - if (insn & 0x8) - if (unwind_pop_register(ctrl, &vsp, 14)) - return -URC_FAILURE; - - ctrl->vrs[SP] = (unsigned long)vsp; - - return URC_OK; -} - -static int unwind_exec_pop_subset_r0_to_r3(struct unwind_ctrl_block *ctrl, - unsigned long mask) -{ - unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; - int reg = 0; - - /* pop R0-R3 according to mask */ - while (mask) - { - if (mask & 1) - if (unwind_pop_register(ctrl, &vsp, reg)) - return -URC_FAILURE; - mask >>= 1; - reg++; - } - ctrl->vrs[SP] = (unsigned long)vsp; - - return URC_OK; -} - -/* - * Execute the current unwind instruction. - */ -static int unwind_exec_insn(struct unwind_ctrl_block *ctrl) -{ - unsigned long insn = unwind_get_byte(ctrl); - int ret = URC_OK; - - LOG_D("%s: insn = %08lx", __func__, insn); - - if ((insn & 0xc0) == 0x00) - ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4; - else if ((insn & 0xc0) == 0x40) - ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4; - else if ((insn & 0xf0) == 0x80) - { - unsigned long mask; - - insn = (insn << 8) | unwind_get_byte(ctrl); - mask = insn & 0x0fff; - if (mask == 0) - { - LOG_W("unwind: 'Refuse to unwind' instruction %04lx", - insn); - return -URC_FAILURE; - } - - ret = unwind_exec_pop_subset_r4_to_r13(ctrl, mask); - if (ret) - goto error; - } - else if ((insn & 0xf0) == 0x90 && - (insn & 0x0d) != 0x0d) - ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f]; - else if ((insn & 0xf0) == 0xa0) - { - ret = unwind_exec_pop_r4_to_rN(ctrl, insn); - if (ret) - goto error; - } - else if (insn == 0xb0) - { - if (ctrl->vrs[PC] == 0) - ctrl->vrs[PC] = ctrl->vrs[LR]; - /* no further processing */ - ctrl->entries = 0; - } - else if (insn == 0xb1) - { - unsigned long mask = unwind_get_byte(ctrl); - - if (mask == 0 || mask & 0xf0) - { - LOG_W("unwind: Spare encoding %04lx", - (insn << 8) | mask); - return -URC_FAILURE; - } - - ret = unwind_exec_pop_subset_r0_to_r3(ctrl, mask); - if (ret) - goto error; - } - else if (insn == 0xb2) - { - unsigned long uleb128 = unwind_get_byte(ctrl); - - ctrl->vrs[SP] += 0x204 + (uleb128 << 2); - } - else - { - LOG_W("unwind: Unhandled instruction %02lx", insn); - return -URC_FAILURE; - } - - LOG_D("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx", __func__, - ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]); - -error: - return ret; -} - -#ifdef RT_BACKTRACE_FUNCTION_NAME -static char *unwind_get_function_name(void *address) -{ - uint32_t flag_word = *(uint32_t *)((char*)address - 4); - - if ((flag_word & 0xff000000) == 0xff000000) - { - return (char *)((char*)address - 4 - (flag_word & 0x00ffffff)); - } - return RT_NULL; -} -#endif - -/* - * Unwind a single frame starting with *sp for the symbol at *pc. It - * updates the *pc and *sp with the new values. - */ -int unwind_frame(struct stackframe *frame, const struct unwind_idx **origin_idx, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]) -{ - unsigned long low; - const struct unwind_idx *idx; - struct unwind_ctrl_block ctrl; - struct rt_thread *rt_c_thread; - - /* store the highest address on the stack to avoid crossing it*/ - low = frame->sp; - rt_c_thread = rt_thread_self(); - ctrl.sp_high = (unsigned long)((char*)rt_c_thread->stack_addr + rt_c_thread->stack_size); - - LOG_D("%s(pc = %08lx lr = %08lx sp = %08lx)", __func__, - frame->pc, frame->lr, frame->sp); - - idx = unwind_find_idx(frame->pc, origin_idx, exidx_start, exidx_end); - if (!idx) - { - LOG_W("unwind: Index not found %08lx", frame->pc); - return -URC_FAILURE; - } - -#ifdef RT_BACKTRACE_FUNCTION_NAME - { - char *fun_name; - fun_name = unwind_get_function_name((void *)prel31_to_addr(&idx->addr_offset)); - if (fun_name) - { - rt_kprintf("0x%08x @ %s\n", frame->pc, fun_name); - } - } -#endif - - ctrl.vrs[FP] = frame->fp; - ctrl.vrs[SP] = frame->sp; - ctrl.vrs[LR] = frame->lr; - ctrl.vrs[PC] = 0; - - if (idx->insn == 1) - /* can't unwind */ - return -URC_FAILURE; - else if ((idx->insn & 0x80000000) == 0) - /* prel31 to the unwind table */ - ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn); - else if ((idx->insn & 0xff000000) == 0x80000000) - /* only personality routine 0 supported in the index */ - ctrl.insn = &idx->insn; - else - { - LOG_W("unwind: Unsupported personality routine %08lx in the index at %x", - idx->insn, idx); - return -URC_FAILURE; - } - - /* check the personality routine */ - if ((*ctrl.insn & 0xff000000) == 0x80000000) - { - ctrl.byte = 2; - ctrl.entries = 1; - } - else if ((*ctrl.insn & 0xff000000) == 0x81000000) - { - ctrl.byte = 1; - ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16); - } - else - { - LOG_W("unwind: Unsupported personality routine %08lx at %x", - *ctrl.insn, ctrl.insn); - return -URC_FAILURE; - } - - ctrl.check_each_pop = 0; - - while (ctrl.entries > 0) - { - int urc; - if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs)) - ctrl.check_each_pop = 1; - urc = unwind_exec_insn(&ctrl); - if (urc < 0) - return urc; - if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.sp_high) - return -URC_FAILURE; - } - - if (ctrl.vrs[PC] == 0) - ctrl.vrs[PC] = ctrl.vrs[LR]; - - /* check for infinite loop */ - if (frame->pc == ctrl.vrs[PC]) - return -URC_FAILURE; - - frame->fp = ctrl.vrs[FP]; - frame->sp = ctrl.vrs[SP]; - frame->lr = ctrl.vrs[LR]; - frame->pc = ctrl.vrs[PC]; - - return URC_OK; -} - -void unwind_backtrace(struct pt_regs *regs, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]) -{ - struct stackframe frame; - const struct unwind_idx *origin_idx = RT_NULL; - - LOG_D("%s(regs = %x)", __func__, regs); - - arm_get_current_stackframe(regs, &frame); - -#ifndef RT_BACKTRACE_FUNCTION_NAME - rt_kprintf("please use: addr2line -e rtthread.elf -a -f %08x\n", frame.pc); -#endif - LOG_D("pc = %08x, sp = %08x", frame.pc, frame.sp); - - while (1) - { - int urc; - - urc = unwind_frame(&frame, &origin_idx, exidx_start, exidx_end); - if (urc < 0) - break; - /* dump_backtrace_entry(where, frame.pc, frame.sp - 4); */ -#ifndef RT_BACKTRACE_FUNCTION_NAME - rt_kprintf(" %08x", frame.pc); -#endif - LOG_D("from: pc = %08x, frame = %08x", frame.pc, frame.sp - 4); - } - rt_kprintf("\n"); -} - -extern const struct unwind_idx __exidx_start[]; -extern const struct unwind_idx __exidx_end[]; - -void rt_unwind(struct rt_hw_exp_stack *regs, unsigned int pc_adj) -{ - struct pt_regs e_regs; - - e_regs.ARM_fp = regs->fp; - e_regs.ARM_sp = regs->sp; - e_regs.ARM_lr = regs->lr; - e_regs.ARM_pc = regs->pc - pc_adj; -#ifdef RT_USING_SMART - if (!lwp_user_accessable((void *)e_regs.ARM_pc, sizeof (void *))) - { - e_regs.ARM_pc = regs->lr - sizeof(void *); - } -#endif - rt_kprintf("backtrace:\n"); - unwind_backtrace(&e_regs, __exidx_start, __exidx_end); -} - -rt_err_t rt_backtrace(void) -{ - struct rt_hw_exp_stack regs; - - __asm volatile ("mov %0, fp":"=r"(regs.fp)); - __asm volatile ("mov %0, sp":"=r"(regs.sp)); - __asm volatile ("mov %0, lr":"=r"(regs.lr)); - __asm volatile ("mov %0, pc":"=r"(regs.pc)); - rt_unwind(®s, 8); - return RT_EOK; -} -#endif /* (__ICCARM__) undefined */ - diff --git a/bsp/rdk/s100/startup/backtrace.h b/bsp/rdk/s100/startup/backtrace.h deleted file mode 100644 index 5e03c2afa77..00000000000 --- a/bsp/rdk/s100/startup/backtrace.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef __BACKTRACE_H -#define __BACKTRACE_H - -#ifndef __ASSEMBLY__ -#include - -/* Unwind reason code according the the ARM EABI documents */ -enum unwind_reason_code -{ - URC_OK = 0, /* operation completed successfully */ - URC_CONTINUE_UNWIND = 8, - URC_FAILURE = 9 /* unspecified failure of some kind */ -}; - -struct unwind_idx -{ - unsigned long addr_offset; - unsigned long insn; -}; - -struct unwind_table -{ - const struct unwind_idx *start; - const struct unwind_idx *origin; - const struct unwind_idx *stop; - unsigned long begin_addr; - unsigned long end_addr; -}; - -struct stackframe -{ - /* - * FP member should hold R7 when CONFIG_THUMB2_KERNEL is enabled - * and R11 otherwise. - */ - unsigned long fp; - unsigned long sp; - unsigned long lr; - unsigned long pc; -}; - -struct pt_regs -{ - unsigned long uregs[18]; -}; - -#define ARM_cpsr uregs[16] -#define ARM_pc uregs[15] -#define ARM_lr uregs[14] -#define ARM_sp uregs[13] -#define ARM_ip uregs[12] -#define ARM_fp uregs[11] -#define ARM_r10 uregs[10] -#define ARM_r9 uregs[9] -#define ARM_r8 uregs[8] -#define ARM_r7 uregs[7] -#define ARM_r6 uregs[6] -#define ARM_r5 uregs[5] -#define ARM_r4 uregs[4] -#define ARM_r3 uregs[3] -#define ARM_r2 uregs[2] -#define ARM_r1 uregs[1] -#define ARM_r0 uregs[0] -#define ARM_ORIG_r0 uregs[17] - -#define instruction_pointer(regs) (regs)->ARM_pc - -#ifdef CONFIG_THUMB2_KERNEL -#define frame_pointer(regs) (regs)->ARM_r7 -#else -#define frame_pointer(regs) (regs)->ARM_fp -#endif - -int unwind_frame(struct stackframe *frame, const struct unwind_idx **origin_idx, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]); -void unwind_backtrace(struct pt_regs *regs, const struct unwind_idx exidx_start[], const struct unwind_idx exidx_end[]); - -void rt_unwind(struct rt_hw_exp_stack *regs, unsigned int pc_adj); -rt_err_t rt_backtrace(void); - -#endif /* !__ASSEMBLY__ */ - -#endif /* __BACKTRACE_H */ - diff --git a/bsp/rdk/s100/startup/cp15.h b/bsp/rdk/s100/startup/cp15.h deleted file mode 100644 index 3742fdc4d7b..00000000000 --- a/bsp/rdk/s100/startup/cp15.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2011-2026, Shanghai Real-Thread Electronic Technology Co.,Ltd - * - * Change Logs: - * Date Author Notes - * 2022-08-29 RT-Thread first version - */ - -#ifndef __CP15_H__ -#define __CP15_H__ - -#ifndef __DSB -#define __DSB() __asm volatile ("dsb" : : : "memory") -#endif - -#ifndef __ISB -#define __ISB() __asm volatile ("isb" : : : "memory") -#endif - -#define __get_cp(cp, op1, Rt, CRn, CRm, op2) \ - __asm volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) -#define __set_cp(cp, op1, Rt, CRn, CRm, op2) \ - __asm volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) -#define __get_cp64(cp, op1, Rt, CRm) \ - __asm volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) -#define __set_cp64(cp, op1, Rt, CRm) \ - __asm volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) - -#endif - diff --git a/bsp/rdk/s100/startup/cp15_gcc.S b/bsp/rdk/s100/startup/cp15_gcc.S deleted file mode 100644 index 1d5b84d5961..00000000000 --- a/bsp/rdk/s100/startup/cp15_gcc.S +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2011-2022, Shanghai Real-Thread Electronic Technology Co.,Ltd - * - * Change Logs: - * Date Author Notes - * 2022-08-29 RT-Thread first version - */ - - -.globl rt_cpu_get_smp_id -rt_cpu_get_smp_id: - mrc p15, #0, r0, c0, c0, #5 - bx lr - -.globl rt_cpu_vector_set_base -rt_cpu_vector_set_base: - /* clear SCTRL.V to customize the vector address */ - mrc p15, #0, r1, c1, c0, #0 - bic r1, #(1 << 13) - mcr p15, #0, r1, c1, c0, #0 - /* set up the vector address */ - mcr p15, #0, r0, c12, c0, #0 - dsb - bx lr - -.globl rt_hw_cpu_dcache_enable -rt_hw_cpu_dcache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_hw_cpu_icache_enable -rt_hw_cpu_icache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -_FLD_MAX_WAY: - .word 0x3ff -_FLD_MAX_IDX: - .word 0x7fff - -.globl rt_cpu_dcache_clean_flush -rt_cpu_dcache_clean_flush: -stmfd sp!, {r0-r12, lr} - bl v7_flush_dcache_all - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate - dsb - isb - ldmfd sp!, {r0-r12, lr} - mov pc, lr - -v7_flush_dcache_all: - dmb @ ensure ordering with previous memory accesses - mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract loc from clidr - mov r3, r3, lsr #23 @ left align loc bit field - beq finished @ if loc is 0, then no need to clean - mov r10, #0 @ start clean at cache level 0 -loop1: - add r2, r10, r10, lsr #1 @ work out 3x current cache level - mov r1, r0, lsr r2 @ extract cache type bits from clidr - and r1, r1, #7 @ mask of the bits for current cache only - cmp r1, #2 @ see what cache we have at this level - blt skip @ skip if no cache, or just i-cache - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr - isb @ isb to sych the new cssr&csidr - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr - and r2, r1, #7 @ extract the length of the cache lines - add r2, r2, #4 @ add 4 (line length offset) - ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximum number on the way size - clz r5, r4 @ find bit position of way size increment - ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract max number of the index size -loop2: - mov r9, r4 @ create working copy of max way size -loop3: - orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 - orr r11, r11, r7, lsl r2 @ factor index number into r11 - mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way - subs r9, r9, #1 @ decrement the way - bge loop3 - subs r7, r7, #1 @ decrement the index - bge loop2 -skip: - add r10, r10, #2 @ increment cache number - cmp r3, r10 - bgt loop1 -finished: - mov r10, #0 @ swith back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr - dsb - isb - mov pc, lr -#if 0 - push {r4-r11} - dmb - mrc p15, #1, r0, c0, c0, #1 @ read clid register - ands r3, r0, #0x7000000 @ get level of coherency - mov r3, r3, lsr #23 - beq finished - mov r10, #0 -loop1: - add r2, r10, r10, lsr #1 - mov r1, r0, lsr r2 - and r1, r1, #7 - cmp r1, #2 - blt skip - mcr p15, #2, r10, c0, c0, #0 - isb - mrc p15, #1, r1, c0, c0, #0 - and r2, r1, #7 - add r2, r2, #4 - ldr r4, _FLD_MAX_WAY - ands r4, r4, r1, lsr #3 - clz r5, r4 - ldr r7, _FLD_MAX_IDX - ands r7, r7, r1, lsr #13 -loop2: - mov r9, r4 -loop3: - orr r11, r10, r9, lsl r5 - orr r11, r11, r7, lsl r2 - mcr p15, #0, r11, c7, c14, #2 - subs r9, r9, #1 - bge loop3 - subs r7, r7, #1 - bge loop2 -skip: - add r10, r10, #2 - cmp r3, r10 - bgt loop1 - -finished: - dsb - isb - pop {r4-r11} - bx lr -#endif -.globl rt_cpu_icache_flush -rt_cpu_icache_flush: - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate - dsb - isb - bx lr - -.globl rt_hw_cpu_dcache_disable -rt_hw_cpu_dcache_disable: - push {r4-r11, lr} - bl rt_cpu_dcache_clean_flush - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - pop {r4-r11, lr} - bx lr - -.globl rt_hw_cpu_icache_disable -rt_hw_cpu_icache_disable: - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr diff --git a/bsp/rdk/s100/startup/cpuport.c b/bsp/rdk/s100/startup/cpuport.c deleted file mode 100644 index 15a258cb64c..00000000000 --- a/bsp/rdk/s100/startup/cpuport.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011-2026, Shanghai Real-Thread Electronic Technology Co.,Ltd - * - * Change Logs: - * Date Author Notes - * 2022-08-29 RT-Thread first version - */ - -#include -#include - -int rt_hw_cpu_id(void) -{ - int cpu_id; - __asm volatile ( - "mrc p15, 0, %0, c0, c0, 5" - :"=r"(cpu_id) - ); - cpu_id &= 0xf; - return cpu_id; -} - -rt_uint64_t get_main_cpu_affval(void) -{ - rt_uint32_t mpidr; - - __asm volatile ( - "mrc p15, 0, %0, c0, c0, 5" - : "=r"(mpidr) - ); - - /* - * GICv3 IROUTER uses Aff3:Aff2:Aff1:Aff0. On this AArch32 port we only - * need the MPIDR affinity fields already provided by the core. - */ - return (rt_uint64_t)(mpidr & 0x00FFFFFFU); -} - -/** - * @addtogroup ARM CPU - */ -/*@{*/ - -/** shutdown CPU */ -void rt_hw_cpu_shutdown() -{ - rt_uint32_t level; - - rt_kprintf("shutdown...\n"); - - level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } -} - -/*@}*/ - diff --git a/bsp/rdk/s100/startup/cpuport.h b/bsp/rdk/s100/startup/cpuport.h deleted file mode 100644 index 4f132e0e1d0..00000000000 --- a/bsp/rdk/s100/startup/cpuport.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2011-2026, Shanghai Real-Thread Electronic Technology Co.,Ltd - * - * Change Logs: - * Date Author Notes - * 2022-08-29 RT-Thread first version - */ - - -#ifndef CPUPORT_H__ -#define CPUPORT_H__ - -/* the exception stack without VFP registers */ -struct rt_hw_exp_stack -{ - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long sp; - unsigned long lr; - unsigned long pc; - unsigned long cpsr; -}; - -struct rt_hw_stack -{ - unsigned long cpsr; - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long lr; - unsigned long pc; -}; - -#define USERMODE 0x10 -#define FIQMODE 0x11 -#define IRQMODE 0x12 -#define SVCMODE 0x13 -#define MONITORMODE 0x16 -#define ABORTMODE 0x17 -#define HYPMODE 0x1b -#define UNDEFMODE 0x1b -#define MODEMASK 0x1f -#define NOINT 0xc0 - -#define T_Bit (1<<5) -#define F_Bit (1<<6) -#define I_Bit (1<<7) -#define A_Bit (1<<8) -#define E_Bit (1<<9) -#define J_Bit (1<<24) - - -/* rt_inline void rt_hw_isb(void) */ -/* { */ -/* __asm volatile ("isb":::"memory"); */ -/* } */ - -/* rt_inline void rt_hw_dmb(void) */ -/* { */ -/* __asm volatile ("dmb":::"memory"); */ -/* } */ - -/* rt_inline void rt_hw_dsb(void) */ -/* { */ -/* __asm volatile ("dsb":::"memory"); */ -/* } */ - -#endif /*CPUPORT_H__*/ - diff --git a/bsp/rdk/s100/startup/gicv3.h b/bsp/rdk/s100/startup/gicv3.h deleted file mode 100644 index 3a7bf3d7418..00000000000 --- a/bsp/rdk/s100/startup/gicv3.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2006-2026, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - */ - -#ifndef __GIC_V3_H__ -#define __GIC_V3_H__ - -#include -#include - -#define __get_gicv3_reg(CR, Rt) __asm volatile("MRC " CR \ - : "=r"(Rt) \ - : \ - : "memory") -#define __set_gicv3_reg(CR, Rt) __asm volatile("MCR " CR \ - : \ - : "r"(Rt) \ - : "memory") - - -/* AArch32 System register interface to GICv3 */ -#define ICC_IAR0 "p15, 0, %0, c12, c8, 0" -#define ICC_IAR1 "p15, 0, %0, c12, c12, 0" -#define ICC_EOIR0 "p15, 0, %0, c12, c8, 1" -#define ICC_EOIR1 "p15, 0, %0, c12, c12, 1" -#define ICC_HPPIR0 "p15, 0, %0, c12, c8, 2" -#define ICC_HPPIR1 "p15, 0, %0, c12, c12, 2" -#define ICC_BPR0 "p15, 0, %0, c12, c8, 3" -#define ICC_BPR1 "p15, 0, %0, c12, c12, 3" -#define ICC_DIR "p15, 0, %0, c12, c11, 1" -#define ICC_PMR "p15, 0, %0, c4, c6, 0" -#define ICC_RPR "p15, 0, %0, c12, c11, 3" -#define ICC_CTLR "p15, 0, %0, c12, c12, 4" -#define ICC_MCTLR "p15, 6, %0, c12, c12, 4" -#define ICC_SRE "p15, 0, %0, c12, c12, 5" -#define ICC_HSRE "p15, 4, %0, c12, c9, 5" -#define ICC_MSRE "p15, 6, %0, c12, c12, 5" -#define ICC_IGRPEN0 "p15, 0, %0, c12, c12, 6" -#define ICC_IGRPEN1 "p15, 0, %0, c12, c12, 7" -#define ICC_MGRPEN1 "p15, 6, %0, c12, c12, 7" - -#define __REG32(x) (*((volatile unsigned int*)((rt_uint32_t)x))) - -#define ROUTED_TO_ALL (1) -#define ROUTED_TO_SPEC (0) - -/** Macro to access the Distributor Control Register (GICD_CTLR) -*/ -#define GICD_CTLR_RWP ((unsigned int)1<<31) -#define GICD_CTLR_E1NWF (1<<7) -#define GICD_CTLR_DS (1<<6) /* 当两种安全模式被同时支持时,可以通过GICD_CTLR.DS==1关闭其中一个,只支持non-secure模式 */ -#define GICD_CTLR_ARE_NS (1<<5) -#define GICD_CTLR_ARE_S (1<<4) -#define GICD_CTLR_ENGRP1S (1<<2) /* secure group 1 */ -#define GICD_CTLR_ENGRP1NS (1<<1) /* non-secure group 1 */ -#define GICD_CTLR_ENGRP0 (1<<0) /* group 0 */ - -/** Macro to access the Redistributor Control Register (GICR_CTLR) -*/ -#define GICR_CTLR_UWP (1<<31) -#define GICR_CTLR_DPG1S (1<<26) -#define GICR_CTLR_DPG1NS (1<<25) -#define GICR_CTLR_DPG0 (1<<24) -#define GICR_CTLR_RWP (1<<3) -#define GICR_CTLR_IR (1<<2) -#define GICR_CTLR_CES (1<<1) -#define GICR_CTLR_EnableLPI (1<<0) - -/** Macro to access the Generic Interrupt Controller Interface (GICC) -*/ -#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00U) -#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04U) -#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08U) -#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0cU) -#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10U) -#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14U) -#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18U) -#define GIC_CPU_IIDR(hw_base) __REG32((hw_base) + 0xFCU) - -/** Macro to access the Generic Interrupt Controller Distributor (GICD) -*/ -#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) -#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004U) -#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080U + ((n)/32U) * 4U) -#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100U + ((n)/32U) * 4U) -#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180U + ((n)/32U) * 4U) -#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200U + ((n)/32U) * 4U) -#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280U + ((n)/32U) * 4U) -#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300U + ((n)/32U) * 4U) -#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380U + ((n)/32U) * 4U) -#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400U + ((n)/4U) * 4U) -#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800U + ((n)/4U) * 4U) -#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00U + ((n)/16U) * 4U) -#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00U) -#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10U + ((n)/4U) * 4U) -#define GIC_DIST_SPENDSGI(hw_base, n) __REG32((hw_base) + 0xf20U + ((n)/4U) * 4U) -#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8U) -#define GIC_DIST_IROUTER_LOW(hw_base, n) __REG32((hw_base) + 0x6000U + (n)*8U) -#define GIC_DIST_IROUTER_HIGH(hw_base, n) __REG32((hw_base) + 0x6000U + (n)*8U + 4) - -/* SGI base address is at 64K offset from Redistributor base address */ -#define GIC_RSGI_OFFSET 0x10000 - -/** Macro to access the Generic Interrupt Controller Redistributor (GICD) -*/ -#define GIC_RDIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) -#define GIC_RDIST_IIDR(hw_base) __REG32((hw_base) + 0x004U) -#define GIC_RDIST_TYPER(hw_base) __REG32((hw_base) + 0x008U) -#define GIC_RDIST_TSTATUSR(hw_base) __REG32((hw_base) + 0x010U) -#define GIC_RDIST_WAKER(hw_base) __REG32((hw_base) + 0x014U) -#define GIC_RDIST_SETLPIR(hw_base) __REG32((hw_base) + 0x040U) -#define GIC_RDIST_CLRLPIR(hw_base) __REG32((hw_base) + 0x048U) -#define GIC_RDIST_PROPBASER(hw_base) __REG32((hw_base) + 0x070U) -#define GIC_RDIST_PENDBASER(hw_base) __REG32((hw_base) + 0x078U) -#define GIC_RDIST_INVLPIR(hw_base) __REG32((hw_base) + 0x0A0U) -#define GIC_RDIST_INVALLR(hw_base) __REG32((hw_base) + 0x0B0U) -#define GIC_RDIST_SYNCR(hw_base) __REG32((hw_base) + 0x0C0U) - -#define GIC_RDISTSGI_IGROUPR0(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n)*4U) -#define GIC_RDISTSGI_ISENABLER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x100U) -#define GIC_RDISTSGI_ICENABLER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x180U) -#define GIC_RDISTSGI_ISPENDR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x200U) -#define GIC_RDISTSGI_ICPENDR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x280U) -#define GIC_RDISTSGI_ISACTIVER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x300U) -#define GIC_RDISTSGI_ICACTIVER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x380U) -#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U) -#define GIC_RDISTSGI_ICFGR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U) -#define GIC_RDISTSGI_ICFGR1(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U) -#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n)*4) -#define GIC_RDISTSGI_NSACR(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) /* 当执行一个非安全模式到安全模式的访问 */ - -#define GIC_RSGI_AFF1_OFFSET 16 -#define GIC_RSGI_AFF2_OFFSET 32 -#define GIC_RSGI_AFF3_OFFSET 48 - -rt_uint32_t arm_gic_cpumask_to_affval(rt_uint32_t *cpu_mask, rt_uint32_t *cluster_id, rt_uint32_t *target_list); -rt_uint64_t get_main_cpu_affval(void); -int arm_gic_get_active_irq(rt_uint32_t index); -void arm_gic_ack(rt_uint32_t index, int irq); - -void arm_gic_mask(rt_uint32_t index, int irq); -void arm_gic_umask(rt_uint32_t index, int irq); - -rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq); -void arm_gic_set_pending_irq(rt_uint32_t index, int irq); -void arm_gic_clear_pending_irq(rt_uint32_t index, int irq); - -void arm_gic_set_configuration(rt_uint32_t index, int irq, rt_uint32_t config); -rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq); - -void arm_gic_clear_active(rt_uint32_t index, int irq); - -void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask); -rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq); - -void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority); -rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq); - -void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority); -rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index); - -void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point); -rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index); - -rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq); - -rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index); - -rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index); - -void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group); -rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq); - -int arm_gic_redist_address_set(rt_uint32_t index, rt_uint32_t redist_addr, rt_uint32_t cpu_id); -int arm_gic_cpu_interface_address_set(rt_uint32_t index, rt_uint32_t interface_addr, rt_uint32_t cpu_id); -int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start); -int arm_gic_cpu_init(rt_uint32_t index); -int arm_gic_redist_init(rt_uint32_t index); - -void arm_gic_dump_type(rt_uint32_t index); -void arm_gic_dump(rt_uint32_t index); - -void arm_gic_set_system_register_enable_mask(rt_uint32_t index, rt_uint32_t value); -rt_uint32_t arm_gic_get_system_register_enable_mask(rt_uint32_t index); -void arm_gic_secondary_cpu_init(void); - -void assemb_dsb_func(); -void assemb_isb_func(); - -#endif - diff --git a/bsp/rdk/s100/startup/interrupt.h b/bsp/rdk/s100/startup/interrupt.h deleted file mode 100644 index db38f7b8d36..00000000000 --- a/bsp/rdk/s100/startup/interrupt.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2006-2026, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-06 Bernard first version - */ - -#ifndef __INTERRUPT_H__ -#define __INTERRUPT_H__ - -#include - -#define INT_IRQ 0x00 -#define INT_FIQ 0x01 - -#define IRQ_MODE_TRIG_LEVEL (0x00) /* Trigger: level triggered interrupt */ -#define IRQ_MODE_TRIG_EDGE (0x01) /* Trigger: edge triggered interrupt */ - -void rt_hw_vector_init(void); - -void rt_hw_interrupt_init(void); -void rt_hw_interrupt_mask(int vector); -void rt_hw_interrupt_umask(int vector); - -int rt_hw_interrupt_get_irq(void); -void rt_hw_interrupt_ack(int vector); - -void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask); -unsigned int rt_hw_interrupt_get_target_cpus(int vector); - -void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode); -unsigned int rt_hw_interrupt_get_triger_mode(int vector); - -void rt_hw_interrupt_set_pending(int vector); -unsigned int rt_hw_interrupt_get_pending(int vector); -void rt_hw_interrupt_clear_pending(int vector); - -void rt_hw_interrupt_set_priority(int vector, unsigned int priority); -unsigned int rt_hw_interrupt_get_priority(int vector); - -void rt_hw_interrupt_set_priority_mask(unsigned int priority); -unsigned int rt_hw_interrupt_get_priority_mask(void); - -int rt_hw_interrupt_set_prior_group_bits(unsigned int bits); -unsigned int rt_hw_interrupt_get_prior_group_bits(void); - -rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, - void *param, const char *name); - -#endif - diff --git a/bsp/rdk/s100/startup/startup_gcc.S b/bsp/rdk/s100/startup/start_gcc.S similarity index 100% rename from bsp/rdk/s100/startup/startup_gcc.S rename to bsp/rdk/s100/startup/start_gcc.S diff --git a/bsp/rdk/s100/startup/trap.c b/bsp/rdk/s100/startup/trap.c deleted file mode 100644 index 45f2b35baf5..00000000000 --- a/bsp/rdk/s100/startup/trap.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (c) 2006-2026, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - */ - -#include -#include -#include -#include -/* #include */ - -#include "interrupt.h" - -#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) -extern long list_thread(void); -#endif -extern void rt_unwind(struct rt_hw_exp_stack *regs, unsigned int pc_adj); -void (*rt_trap_hook)(struct rt_hw_exp_stack *regs, const char *ex, unsigned int exception_type); - -static void rt_hw_show_backtrace(struct rt_hw_exp_stack *regs) -{ - rt_unwind(regs, 0U); -} - -enum -{ - RT_HW_EL2_TRAP_UNDEF = 0, - RT_HW_EL2_TRAP_PABT, - RT_HW_EL2_TRAP_DABT, - RT_HW_EL2_TRAP_IRQ, - RT_HW_EL2_TRAP_FIQ, - RT_HW_EL2_TRAP_HVC, - RT_HW_EL2_TRAP_RESV, -}; - -void rt_hw_trap_el2(struct rt_hw_exp_stack *regs, unsigned int trap_id) -{ - const char *ex; - unsigned int exception_type; - - switch (trap_id) - { - case RT_HW_EL2_TRAP_UNDEF: - ex = "undefined instruction"; - exception_type = UND_EXCEPTION; - break; - case RT_HW_EL2_TRAP_PABT: - ex = "prefetch abort"; - exception_type = PABT_EXCEPTION; - break; - case RT_HW_EL2_TRAP_DABT: - ex = "data abort"; - exception_type = DABT_EXCEPTION; - break; - case RT_HW_EL2_TRAP_IRQ: - ex = "unexpected IRQ"; - exception_type = RESV_EXCEPTION; - break; - case RT_HW_EL2_TRAP_FIQ: - ex = "unexpected FIQ"; - exception_type = RESV_EXCEPTION; - break; - case RT_HW_EL2_TRAP_HVC: - ex = "unexpected HVC"; - exception_type = RESV_EXCEPTION; - break; - case RT_HW_EL2_TRAP_RESV: - default: - ex = "reserved trap"; - exception_type = RESV_EXCEPTION; - break; - } - - if (rt_trap_hook == RT_NULL) - { - rt_kprintf("EL2 %s:\n", ex); - rt_hw_show_register(regs); - rt_hw_show_backtrace(regs); -#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) - list_thread(); -#endif - rt_hw_cpu_shutdown(); - } - else - { - rt_trap_hook(regs, ex, exception_type); - } -} - -/** - * The software interrupt instruction (SWI) is used for entering - * Supervisor mode, usually to request a particular supervisor - * function. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_svc(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("software interrupt\n"); - rt_hw_show_register(regs); - rt_hw_show_backtrace(regs); -#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; - -/** - * This function set the hook, which is invoked on fault exception handling. - * - * @param exception_handle the exception handling hook function. - */ -void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)) -{ - rt_exception_hook = exception_handle; -} - -/** - * this function will show registers of CPU - * - * @param regs the registers point - */ -void rt_hw_show_register(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("Execption:\n"); - rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); - rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); - rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); - rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); - rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); - rt_kprintf("cpsr:0x%08x\n", regs->cpsr); - if (rt_exception_hook != RT_NULL) - { - rt_err_t result; - - result = rt_exception_hook(regs); - if (result == RT_EOK) return; - } -} - -/** - * This function will set a hook function to trap handler. - * - * @param hook the hook function - */ -void rt_hw_trap_set_hook(void (*hook)(struct rt_hw_exp_stack *regs, const char *ex, unsigned int exception_type)) -{ - rt_trap_hook = hook; -} - -/** - * When comes across an instruction which it cannot handle, - * it takes the undefined instruction trap. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) -{ - if (rt_trap_hook == RT_NULL) - { - rt_kprintf("undefined instruction:\n"); - rt_hw_show_register(regs); - rt_hw_show_backtrace(regs); -#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) - list_thread(); -#endif - rt_hw_cpu_shutdown(); - } - else - { - rt_trap_hook(regs, "undefined instruction", UND_EXCEPTION); - } -} - -/** - * The software interrupt instruction (SWI) is used for entering - * Supervisor mode, usually to request a particular supervisor - * function. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) -{ - if (rt_trap_hook == RT_NULL) - { - rt_kprintf("software interrupt:\n"); - rt_hw_show_register(regs); - rt_hw_show_backtrace(regs); -#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) - list_thread(); -#endif - rt_hw_cpu_shutdown(); - } - else - { - rt_trap_hook(regs, "software instruction", SWI_EXCEPTION); - } -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during an instruction prefetch. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) -{ - if (rt_trap_hook == RT_NULL) - { - rt_kprintf("prefetch abort:\n"); - rt_hw_show_register(regs); - rt_hw_show_backtrace(regs); -#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) - list_thread(); -#endif - rt_hw_cpu_shutdown(); - } - else - { - rt_trap_hook(regs, "prefetch abort", PABT_EXCEPTION); - } -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during a data access. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) -{ - if (rt_trap_hook == RT_NULL) - { - rt_kprintf("data abort:"); - rt_hw_show_register(regs); - rt_hw_show_backtrace(regs); -#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) - list_thread(); -#endif - rt_hw_cpu_shutdown(); - } - else - { - rt_trap_hook(regs, "data abort", DABT_EXCEPTION); - } -} - -/** - * Normally, system will never reach here - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) -{ - if (rt_trap_hook == RT_NULL) - { - rt_kprintf("reserved trap:\n"); - rt_hw_show_register(regs); - rt_hw_show_backtrace(regs); -#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS) - list_thread(); -#endif - rt_hw_cpu_shutdown(); - } - else - { - rt_trap_hook(regs, "reserved trap", RESV_EXCEPTION); - } -} - -void rt_hw_trap_irq(void) -{ - void *param; - int int_ack; - int ir; - volatile rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - int_ack = rt_hw_interrupt_get_irq(); - - ir = int_ack & GIC_ACK_INTID_MASK; - if (ir == 1023) - { - /* Spurious interrupt */ - return; - } - - /* get interrupt service routine */ - isr_func = isr_table[ir].handler; - -#ifdef RT_USING_INTERRUPT_INFO - isr_table[ir].counter++; -#endif - if (isr_func) - { - /* Interrupt for myself. */ - param = isr_table[ir].param; - /* turn to interrupt service routine */ - isr_func(ir, param); - } - - /* end of interrupt */ - rt_hw_interrupt_ack(int_ack); -} - -void rt_hw_trap_fiq(void) -{ - void *param; - int ir; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - ir = rt_hw_interrupt_get_irq(); - /* get interrupt service routine */ - isr_func = isr_table[ir].handler; - param = isr_table[ir].param; - - /* turn to interrupt service routine */ - isr_func(ir, param); - - /* end of interrupt */ - rt_hw_interrupt_ack(ir); -} - diff --git a/bsp/rdk/s100/startup/vector_gcc.S b/bsp/rdk/s100/startup/vector_gcc.S index 64b4d7636bc..b622ace660b 100644 --- a/bsp/rdk/s100/startup/vector_gcc.S +++ b/bsp/rdk/s100/startup/vector_gcc.S @@ -8,47 +8,36 @@ * 2013-07-05 Bernard the first version */ +.macro push_svc_reg pc_adjust + sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + mov r0, sp + mrs r6, spsr @/* Save CPSR */ + sub r5, lr, #\pc_adjust + str r5, [r0, #15*4] @/* Push fault PC */ + str r6, [r0, #16*4] @/* Push CPSR */ + cps #0x13 @/* Switch to SVC mode */ + str sp, [r0, #13*4] @/* Save calling SP */ + str lr, [r0, #14*4] @/* Save calling PC */ +.endm - .globl turnon_VFP -turnon_VFP: - @ Enable FPV - STMDB sp!, {r0} - fmrx r0, fpexc - orr r0, r0, #0x40000000 - fmxr fpexc, r0 - LDMIA sp!, {r0} - subs pc, lr, #4 - - .macro push_svc_reg pc_adjust - sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ - stmia sp, {r0 - r12} @/* Calling r0-r12 */ - mov r0, sp - mrs r6, spsr @/* Save CPSR */ - sub r5, lr, #\pc_adjust - str r5, [r0, #15*4] @/* Push fault PC */ - str r6, [r0, #16*4] @/* Push CPSR */ - cps #0x13 @/* Switch to SVC mode */ - str sp, [r0, #13*4] @/* Save calling SP */ - str lr, [r0, #14*4] @/* Save calling PC */ - .endm - - /* - * EL2 exceptions are unexpected in the normal RT-Thread runtime because - * the core has already descended into EL1. Keep the SDK policy simple: - * capture a minimal register frame for diagnostics, then stop. - */ - .macro push_hyp_reg pc_adjust - mov r7, sp - sub sp, sp, #17 * 4 - stmia sp, {r0 - r12} - mov r0, sp - str r7, [r0, #13*4] - str lr, [r0, #14*4] - sub r6, lr, #\pc_adjust - str r6, [r0, #15*4] - mrs r6, spsr - str r6, [r0, #16*4] - .endm +/* + * EL2 exceptions are unexpected in the normal RT-Thread runtime because + * the core has already descended into EL1. Keep the SDK policy simple: + * capture a minimal register frame for diagnostics, then stop. + */ +.macro push_hyp_reg pc_adjust + mov r7, sp + sub sp, sp, #17 * 4 + stmia sp, {r0 - r12} + mov r0, sp + str r7, [r0, #13*4] + str lr, [r0, #14*4] + sub r6, lr, #\pc_adjust + str r6, [r0, #15*4] + mrs r6, spsr + str r6, [r0, #16*4] +.endm .globl SWI_Handler SWI_Handler: @@ -123,47 +112,40 @@ __no_vfp_frame_ldr_fiq: EL2_Undefined_Handler: push_hyp_reg 4 mov r1, #0 - bl rt_hw_trap_el2 b . .globl EL2_Prefetch_Handler EL2_Prefetch_Handler: push_hyp_reg 4 mov r1, #1 - bl rt_hw_trap_el2 b . .globl EL2_Abort_Handler EL2_Abort_Handler: push_hyp_reg 8 mov r1, #2 - bl rt_hw_trap_el2 b . .globl EL2_IRQ_Handler EL2_IRQ_Handler: push_hyp_reg 4 mov r1, #3 - bl rt_hw_trap_el2 b . .globl EL2_FIQ_Handler EL2_FIQ_Handler: push_hyp_reg 4 mov r1, #4 - bl rt_hw_trap_el2 b . .globl EL2_HVC_Handler EL2_HVC_Handler: push_hyp_reg 4 mov r1, #5 - bl rt_hw_trap_el2 b . .globl EL2_Trap_Handler EL2_Trap_Handler: push_hyp_reg 4 mov r1, #6 - bl rt_hw_trap_el2 b . From 972805575d506cf335534bb6e85df75434abf24f Mon Sep 17 00:00:00 2001 From: rcitach Date: Wed, 22 Apr 2026 07:49:37 +0000 Subject: [PATCH 5/6] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B8=B2=E5=8F=A3?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=EF=BC=8C=E4=BF=AE=E6=94=B9=E6=B3=A2=E7=89=B9?= =?UTF-8?q?=E7=8E=87=E9=85=8D=E7=BD=AE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/rdk/s100/drivers/drv_uart_v2.c | 442 +++++++++++++++++------------ 1 file changed, 256 insertions(+), 186 deletions(-) diff --git a/bsp/rdk/s100/drivers/drv_uart_v2.c b/bsp/rdk/s100/drivers/drv_uart_v2.c index d20643495a1..5453e5039d3 100644 --- a/bsp/rdk/s100/drivers/drv_uart_v2.c +++ b/bsp/rdk/s100/drivers/drv_uart_v2.c @@ -8,17 +8,19 @@ * 2026-04-20 rcitach first version */ - #include #include #include "interrupt.h" #ifdef RT_USING_SERIAL_V2 -#define UART_MAX_COUNT (3u) +#if !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6) +#error "Please define at least one BSP_USING_UARTx" +#endif + #define UART_SYS_CLK (200000000u) #define UART_CONFIG_TIMEOUT (0xffu) -#define UART_FCR_DEFVAL (UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR) +#define UART_BAUD_DIV_INT_MAX (0xffffu) #define SYS_REG_UART_CTRL ((volatile rt_uint32_t *)0x23660084u) @@ -30,12 +32,17 @@ #define UART_CTRL_UART5_RX_IN_MASK (0x00000010u) #define UART_CTRL_UART6_RX_IN_MASK (0x00000100u) +#define UART4_IRQn (45) +#define UART5_IRQn (46) +#define UART6_IRQn (47) + #define UART_FCR_FIFO_DIS (0x00u) #define UART_FCR_FIFO_EN (0x01u) #define UART_FCR_CLEAR_RCVR (0x02u) #define UART_FCR_CLEAR_XMIT (0x04u) #define UART_FCR_RXSR (0x02u) #define UART_FCR_TXSR (0x04u) +#define UART_FCR_DEFVAL (UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR) #define UART_FCR_RX_TRIGGER_MASK (0xC0u) #define UART_FCR_RX_TRIGGER_8 (0x80u) @@ -46,7 +53,6 @@ #define UART_LCR_EPS (0x10u) #define UART_LCR_DLAB (0x80u) -#define UART_LSR_DR (0x01u) #define UART_LSR_THRE (0x20u) #define UART_IIR_NO_INT (0x01u) @@ -57,17 +63,11 @@ #define UART_IIR_BUSY_DETECT (0x07u) #define UART_IIR_CHAR_TIMEOUT (0x0cu) -/* - * These are the definitions for the Interrupt Enable Register - */ -#define UART_IER_MSI (0x08U) /**< Enable Modem status interrupt */ -#define UART_IER_RLSI (0x04U) /**< Enable receiver line status interrupt */ -#define UART_IER_THRI (0x02U) /**< Enable Transmitter holding register int. */ -#define UART_IER_RDI (0x01U) /**< Enable receiver data interrupt */ - -#define UART4_IRQn (45) -#define UART5_IRQn (46) -#define UART6_IRQn (47) +#define UART_IER_MSI (0x08u) +#define UART_IER_RLSI (0x04u) +#define UART_IER_THRI (0x02u) +#define UART_IER_RDI (0x01u) +#define UART_IER_ALL (UART_IER_RDI | UART_IER_THRI | UART_IER_RLSI | UART_IER_MSI) #define UART_USR_BUSY (0x01u) #define UART_USR_TFNF (0x02u) @@ -75,133 +75,196 @@ typedef struct { - volatile rt_uint32_t RBR; - volatile rt_uint32_t IER; - volatile rt_uint32_t FCR; - volatile rt_uint32_t LCR; - volatile rt_uint32_t MCR; - volatile rt_uint32_t LSR; - volatile rt_uint32_t MSR; - volatile rt_uint32_t RESERVED1[21]; - volatile rt_uint32_t FAR; - volatile rt_uint32_t TFR; - volatile rt_uint32_t RFW; - volatile rt_uint32_t USR; - volatile rt_uint32_t TFL; - volatile rt_uint32_t RFL; - volatile rt_uint32_t RESERVED2[7]; - volatile rt_uint32_t HTX; - volatile rt_uint32_t DMASA; - volatile rt_uint32_t RESERVED3[5]; - volatile rt_uint32_t DLF; + volatile rt_uint32_t rbr; + volatile rt_uint32_t ier; + volatile rt_uint32_t fcr; + volatile rt_uint32_t lcr; + volatile rt_uint32_t mcr; + volatile rt_uint32_t lsr; + volatile rt_uint32_t msr; + volatile rt_uint32_t reserved1[21]; + volatile rt_uint32_t far; + volatile rt_uint32_t tfr; + volatile rt_uint32_t rfw; + volatile rt_uint32_t usr; + volatile rt_uint32_t tfl; + volatile rt_uint32_t rfl; + volatile rt_uint32_t reserved2[7]; + volatile rt_uint32_t htx; + volatile rt_uint32_t dmasa; + volatile rt_uint32_t reserved3[5]; + volatile rt_uint32_t dlf; } s100_uart_reg_t; -struct s100_uart +struct s100_uart_device { - struct rt_serial_device serial; - s100_uart_reg_t *regs; + rt_ubase_t hw_base; rt_uint32_t rx_mask; int irqno; + struct rt_serial_device *serial; + const char *device_name; rt_uint16_t rx_bufsz; rt_uint16_t tx_bufsz; rt_uint32_t fcr_shadow; - const char *name; }; #if defined(BSP_USING_UART4) -#define S100_UART4_DESC \ - { \ - .regs = (s100_uart_reg_t *)UART_4_BASE, \ - .rx_mask = UART_CTRL_UART4_RX_IN_MASK, \ - .irqno = UART4_IRQn, \ - .rx_bufsz = BSP_UART4_RX_BUFSIZE, \ - .tx_bufsz = BSP_UART4_TX_BUFSIZE, \ - .name = "uart4", \ - } +static struct rt_serial_device serial4; #endif #if defined(BSP_USING_UART5) -#define S100_UART5_DESC \ - { \ - .regs = (s100_uart_reg_t *)UART_5_BASE, \ - .rx_mask = UART_CTRL_UART5_RX_IN_MASK, \ - .irqno = UART5_IRQn, \ - .rx_bufsz = BSP_UART5_RX_BUFSIZE, \ - .tx_bufsz = BSP_UART5_TX_BUFSIZE, \ - .name = "uart5", \ - } +static struct rt_serial_device serial5; #endif #if defined(BSP_USING_UART6) -#define S100_UART6_DESC \ - { \ - .regs = (s100_uart_reg_t *)UART_6_BASE, \ - .rx_mask = UART_CTRL_UART6_RX_IN_MASK, \ - .irqno = UART6_IRQn, \ - .rx_bufsz = BSP_UART6_RX_BUFSIZE, \ - .tx_bufsz = BSP_UART6_TX_BUFSIZE, \ - .name = "uart6", \ - } +static struct rt_serial_device serial6; #endif -static struct s100_uart s100_uarts[] = +static struct s100_uart_device s100_uart_devices[] = { #if defined(BSP_USING_UART4) - S100_UART4_DESC, + { + .hw_base = UART_4_BASE, + .rx_mask = UART_CTRL_UART4_RX_IN_MASK, + .irqno = UART4_IRQn, + .serial = &serial4, + .device_name = "uart4", + .rx_bufsz = BSP_UART4_RX_BUFSIZE, + .tx_bufsz = BSP_UART4_TX_BUFSIZE, + }, #endif - #if defined(BSP_USING_UART5) - S100_UART5_DESC, + { + .hw_base = UART_5_BASE, + .rx_mask = UART_CTRL_UART5_RX_IN_MASK, + .irqno = UART5_IRQn, + .serial = &serial5, + .device_name = "uart5", + .rx_bufsz = BSP_UART5_RX_BUFSIZE, + .tx_bufsz = BSP_UART5_TX_BUFSIZE, + }, #endif - #if defined(BSP_USING_UART6) - S100_UART6_DESC, + { + .hw_base = UART_6_BASE, + .rx_mask = UART_CTRL_UART6_RX_IN_MASK, + .irqno = UART6_IRQn, + .serial = &serial6, + .device_name = "uart6", + .rx_bufsz = BSP_UART6_RX_BUFSIZE, + .tx_bufsz = BSP_UART6_TX_BUFSIZE, + }, #endif - }; -static void s100_uart_config_default(struct s100_uart *uart) +static s100_uart_reg_t *s100_uart_regs(struct s100_uart_device *uart) +{ + return (s100_uart_reg_t *)uart->hw_base; +} + +static struct s100_uart_device *s100_uart_from_serial(struct rt_serial_device *serial) +{ + return (struct s100_uart_device *)serial->parent.user_data; +} + +static rt_ubase_t s100_uart_ctrl_arg_translate(rt_ubase_t ctrl_arg) +{ + if (ctrl_arg & (RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING)) + { + return RT_DEVICE_FLAG_INT_RX; + } + + if (ctrl_arg & (RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING)) + { + return RT_DEVICE_FLAG_INT_TX; + } + + return ctrl_arg; +} + +static void s100_uart_disable_irq(struct s100_uart_device *uart, rt_ubase_t ctrl_arg) +{ + s100_uart_reg_t *regs = s100_uart_regs(uart); + + if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) + { + regs->ier &= ~(UART_IER_RDI | UART_IER_RLSI); + } + else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX) + { + regs->ier &= ~UART_IER_THRI; + } +} + +static void s100_uart_enable_irq(struct s100_uart_device *uart, rt_ubase_t ctrl_arg) +{ + s100_uart_reg_t *regs = s100_uart_regs(uart); + + if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) + { + regs->ier |= (UART_IER_RDI | UART_IER_RLSI); + rt_hw_interrupt_umask(uart->irqno); + } + else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX) + { + regs->ier |= UART_IER_THRI; + rt_hw_interrupt_umask(uart->irqno); + } +} + +static void s100_uart_config_default(struct s100_uart_device *uart) { struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; config.baud_rate = BAUD_RATE_921600; config.rx_bufsz = uart->rx_bufsz; config.tx_bufsz = uart->tx_bufsz; - - uart->serial.config = config; + uart->serial->config = config; } - -static void s100_uart_rx_drain(struct s100_uart *uart) +static void s100_uart_rx_drain(struct rt_serial_device *serial) { + struct s100_uart_device *uart; + s100_uart_reg_t *regs; rt_bool_t rx_indicated = RT_FALSE; - while ((uart->regs->USR & UART_USR_RFNE) != 0u) + RT_ASSERT(serial != RT_NULL); + + uart = s100_uart_from_serial(serial); + regs = s100_uart_regs(uart); + + while ((regs->usr & UART_USR_RFNE) != 0u) { - rt_uint8_t ch = (rt_uint8_t)(uart->regs->RBR & 0xffu); + rt_uint8_t ch = (rt_uint8_t)(regs->rbr & 0xffu); - if (uart->serial.serial_rx != RT_NULL) + if (serial->serial_rx != RT_NULL) { - rt_hw_serial_control_isr(&uart->serial, RT_HW_SERIAL_CTRL_PUTC, &ch); + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &ch); rx_indicated = RT_TRUE; } } if (rx_indicated != RT_FALSE) { - rt_hw_serial_isr(&uart->serial, RT_SERIAL_EVENT_RX_IND); + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } } static void s100_uart_isr(int vector, void *param) { - struct s100_uart *uart = (struct s100_uart *)param; + struct rt_serial_device *serial = (struct rt_serial_device *)param; + struct s100_uart_device *uart; + s100_uart_reg_t *regs; rt_uint32_t iir; RT_UNUSED(vector); + RT_ASSERT(serial != RT_NULL); + + uart = s100_uart_from_serial(serial); + regs = s100_uart_regs(uart); /* IIR shares the FCR offset; read it with IIR semantics here. */ - iir = *((volatile rt_uint32_t *)&uart->regs->FCR) & 0x0fu; + iir = *((volatile rt_uint32_t *)®s->fcr) & 0x0fu; if ((iir & UART_IIR_NO_INT) != 0u) { return; @@ -211,15 +274,14 @@ static void s100_uart_isr(int vector, void *param) { case UART_IIR_RDI: case UART_IIR_CHAR_TIMEOUT: - s100_uart_rx_drain(uart); + s100_uart_rx_drain(serial); break; case UART_IIR_RLSI: - /* Reading LSR clears line status sources, then drain any pending data. */ - (void)uart->regs->LSR; - s100_uart_rx_drain(uart); + (void)regs->lsr; + s100_uart_rx_drain(serial); break; case UART_IIR_BUSY_DETECT: - (void)uart->regs->USR; + (void)regs->usr; break; case UART_IIR_THRI: default: @@ -227,31 +289,31 @@ static void s100_uart_isr(int vector, void *param) } } -static void s100_uart_clear_irq(struct s100_uart *uart) +static void s100_uart_fcr_write(struct s100_uart_device *uart, rt_uint32_t val) { - uart->regs->IER &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_THRI | UART_IER_MSI); -} + s100_uart_reg_t *regs = s100_uart_regs(uart); -static void s100_uart_fcr_write(struct s100_uart *uart, rt_uint32_t val) -{ uart->fcr_shadow = val; - uart->regs->FCR = uart->fcr_shadow; + regs->fcr = uart->fcr_shadow; } -static void s100_uart_set_rx_trigger(struct s100_uart *uart, rt_uint32_t trigger) +static void s100_uart_set_rx_trigger(struct s100_uart_device *uart, rt_uint32_t trigger) { + s100_uart_reg_t *regs = s100_uart_regs(uart); + uart->fcr_shadow &= ~UART_FCR_CLEAR_RCVR; uart->fcr_shadow &= ~UART_FCR_CLEAR_XMIT; uart->fcr_shadow &= ~UART_FCR_RX_TRIGGER_MASK; uart->fcr_shadow |= trigger; - uart->regs->FCR = uart->fcr_shadow; + regs->fcr = uart->fcr_shadow; } -static rt_err_t s100_uart_config_prepare(struct s100_uart *uart) +static rt_err_t s100_uart_config_prepare(struct s100_uart_device *uart) { + s100_uart_reg_t *regs = s100_uart_regs(uart); rt_uint32_t timeout = UART_CONFIG_TIMEOUT; - while (((uart->regs->USR & UART_USR_BUSY) != 0u) && (timeout != 0u)) + while (((regs->usr & UART_USR_BUSY) != 0u) && (timeout != 0u)) { s100_uart_fcr_write(uart, UART_FCR_FIFO_DIS); s100_uart_fcr_write(uart, UART_FCR_CLEAR_RCVR); @@ -262,8 +324,9 @@ static rt_err_t s100_uart_config_prepare(struct s100_uart *uart) return (timeout != 0u) ? RT_EOK : -RT_ETIMEOUT; } -static void s100_uart_set_baud(struct s100_uart *uart, rt_uint32_t baud_rate) +static rt_err_t s100_uart_set_baud(struct s100_uart_device *uart, rt_uint32_t baud_rate) { + s100_uart_reg_t *regs = s100_uart_regs(uart); rt_uint32_t baud_div_x64; rt_uint32_t baud_div_int; rt_uint32_t baud_div_fraction; @@ -274,17 +337,27 @@ static void s100_uart_set_baud(struct s100_uart *uart, rt_uint32_t baud_rate) { baud_div_int = 1u; } + + if (baud_div_int > UART_BAUD_DIV_INT_MAX) + { + return -RT_EINVAL; + } + baud_div_fraction = baud_div_x64 - (baud_div_int * 64u); - uart->regs->LCR |= UART_LCR_DLAB; - uart->regs->DLF = baud_div_fraction; - uart->regs->RBR = baud_div_int & 0xffu; - uart->regs->LCR &= ~UART_LCR_DLAB; + regs->lcr |= UART_LCR_DLAB; + regs->ier = (baud_div_int >> 8) & 0xffu; + regs->dlf = baud_div_fraction; + regs->rbr = baud_div_int & 0xffu; + regs->lcr &= ~UART_LCR_DLAB; + + return RT_EOK; } -static rt_err_t s100_uart_set_lcr(struct s100_uart *uart, struct serial_configure *cfg) +static rt_err_t s100_uart_set_lcr(struct s100_uart_device *uart, struct serial_configure *cfg) { - rt_uint32_t lcr = 0; + s100_uart_reg_t *regs = s100_uart_regs(uart); + rt_uint32_t lcr = 0u; switch (cfg->data_bits) { @@ -323,25 +396,28 @@ static rt_err_t s100_uart_set_lcr(struct s100_uart *uart, struct serial_configur return -RT_EINVAL; } - uart->regs->LCR &= ~(UART_LCR_WLS_MSK | UART_LCR_STB | UART_LCR_PEN | UART_LCR_EPS); - uart->regs->LCR |= lcr; + regs->lcr &= ~(UART_LCR_WLS_MSK | UART_LCR_STB | UART_LCR_PEN | UART_LCR_EPS); + regs->lcr |= lcr; return RT_EOK; } -static void s100_uart_set_fifo(struct s100_uart *uart) +static void s100_uart_set_fifo(struct s100_uart_device *uart) { - s100_uart_clear_irq(uart); + s100_uart_reg_t *regs = s100_uart_regs(uart); + rt_uint32_t irq_state = regs->ier & UART_IER_ALL; + + regs->ier &= ~UART_IER_ALL; s100_uart_fcr_write(uart, UART_FCR_DEFVAL); s100_uart_set_rx_trigger(uart, UART_FCR_RX_TRIGGER_8); + regs->ier = irq_state; } static rt_err_t s100_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { - - - struct s100_uart *uart; + struct s100_uart_device *uart; + s100_uart_reg_t *regs; rt_err_t ret; RT_ASSERT(serial != RT_NULL); @@ -352,115 +428,101 @@ static rt_err_t s100_uart_configure(struct rt_serial_device *serial, return -RT_EINVAL; } - uart = (struct s100_uart *)serial->parent.user_data; + uart = s100_uart_from_serial(serial); + regs = s100_uart_regs(uart); (*(uint32_t *)SYS_REG_UART_CTRL) |= uart->rx_mask; - uart->regs->MCR = 0u; + regs->mcr = 0u; ret = s100_uart_config_prepare(uart); if (ret == RT_EOK) { - s100_uart_set_baud(uart, cfg->baud_rate); + ret = s100_uart_set_baud(uart, cfg->baud_rate); + } + if (ret == RT_EOK) + { ret = s100_uart_set_lcr(uart, cfg); + } + if (ret == RT_EOK) + { s100_uart_set_fifo(uart); } (*(uint32_t *)SYS_REG_UART_CTRL) &= ~uart->rx_mask; - return ret; } static rt_err_t s100_uart_control(struct rt_serial_device *serial, int cmd, void *arg) { - struct s100_uart *uart; - rt_ubase_t ctrl_arg = (rt_ubase_t) arg; + struct s100_uart_device *uart; + rt_ubase_t ctrl_arg; RT_ASSERT(serial != RT_NULL); - uart = (struct s100_uart *)serial->parent.user_data; - - if(ctrl_arg & (RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING)) - { - ctrl_arg = RT_DEVICE_FLAG_INT_RX; - } - else if(ctrl_arg & (RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING)) - { - ctrl_arg = RT_DEVICE_FLAG_INT_TX; - } + uart = s100_uart_from_serial(serial); + ctrl_arg = s100_uart_ctrl_arg_translate((rt_ubase_t)arg); switch (cmd) { - case RT_DEVICE_CTRL_CLR_INT: - if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) - { - /* disable rx irq */ - uart->regs->IER &= ~(UART_IER_RDI | UART_IER_RLSI); - } - else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX) - { - /* disable tx irq */ - uart->regs->IER &= (~UART_IER_THRI); - } - break; - - case RT_DEVICE_CTRL_SET_INT: - if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) - { - /* enable rx irq */ - uart->regs->IER |= (UART_IER_RDI | UART_IER_RLSI); - rt_hw_interrupt_umask(uart->irqno); - - } else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX) - { - /* enable tx irq */ - uart->regs->IER |= UART_IER_THRI; - rt_hw_interrupt_umask(uart->irqno); - } - - break; - case RT_DEVICE_CTRL_CONFIG: - return s100_uart_control(serial, RT_DEVICE_CTRL_SET_INT, (void *)ctrl_arg); - case RT_DEVICE_CTRL_CLOSE: - uart->regs->IER &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_THRI | UART_IER_MSI); - rt_hw_interrupt_mask(uart->irqno); - break; - default: - break; + case RT_DEVICE_CTRL_CLR_INT: + s100_uart_disable_irq(uart, ctrl_arg); + break; + + case RT_DEVICE_CTRL_SET_INT: + case RT_DEVICE_CTRL_CONFIG: + if (ctrl_arg != RT_DEVICE_FLAG_INT_RX && ctrl_arg != RT_DEVICE_FLAG_INT_TX) + { + return -RT_EINVAL; + } + s100_uart_enable_irq(uart, ctrl_arg); + break; + + case RT_DEVICE_CTRL_CLOSE: + s100_uart_regs(uart)->ier &= ~UART_IER_ALL; + rt_hw_interrupt_mask(uart->irqno); + break; + + default: + break; } + return RT_EOK; } -static int s100_uart_putc(struct rt_serial_device *serial, char c) +static int s100_uart_putc(struct rt_serial_device *serial, char ch) { - - struct s100_uart *uart; + struct s100_uart_device *uart; + s100_uart_reg_t *regs; RT_ASSERT(serial != RT_NULL); - uart = (struct s100_uart *)serial->parent.user_data; + uart = s100_uart_from_serial(serial); + regs = s100_uart_regs(uart); - while ((uart->regs->LSR & UART_LSR_THRE) == 0u) + while ((regs->lsr & UART_LSR_THRE) == 0u) { } - uart->regs->RBR = (rt_uint8_t)c; + regs->rbr = (rt_uint8_t)ch; return 1; } static int s100_uart_getc(struct rt_serial_device *serial) { - struct s100_uart *uart; + struct s100_uart_device *uart; + s100_uart_reg_t *regs; RT_ASSERT(serial != RT_NULL); - uart = (struct s100_uart *)serial->parent.user_data; + uart = s100_uart_from_serial(serial); + regs = s100_uart_regs(uart); - if ((uart->regs->USR & UART_USR_RFNE) == 0u) + if ((regs->usr & UART_USR_RFNE) == 0u) { return -1; } - return (int)(uart->regs->RBR & 0xffu); + return (int)(regs->rbr & 0xffu); } static rt_ssize_t s100_uart_transmit(struct rt_serial_device *serial, @@ -468,18 +530,23 @@ static rt_ssize_t s100_uart_transmit(struct rt_serial_device *serial, rt_size_t size, rt_uint32_t tx_flag) { + struct s100_uart_device *uart; + s100_uart_reg_t *regs; rt_size_t i; RT_ASSERT(serial != RT_NULL); RT_ASSERT(buf != RT_NULL); RT_UNUSED(tx_flag); + uart = s100_uart_from_serial(serial); + regs = s100_uart_regs(uart); + for (i = 0; i < size; i++) { - while ((((struct s100_uart *)serial->parent.user_data)->regs->USR & UART_USR_TFNF) == 0u) + while ((regs->usr & UART_USR_TFNF) == 0u) { } - s100_uart_putc(serial, (char)buf[i]); + regs->rbr = buf[i]; } return size; @@ -499,26 +566,29 @@ int rt_hw_uart_init(void) rt_err_t ret = RT_EOK; rt_size_t i; - for(i = 0; i < sizeof(s100_uarts) / sizeof(s100_uarts[0]); i++) + for (i = 0; i < sizeof(s100_uart_devices) / sizeof(s100_uart_devices[0]); i++) { - s100_uarts[i].serial.ops = &s100_uart_ops; - s100_uart_config_default(&s100_uarts[i]); - s100_uarts[i].serial.parent.user_data = &s100_uarts[i]; + s100_uart_config_default(&s100_uart_devices[i]); + s100_uart_devices[i].serial->ops = &s100_uart_ops; + s100_uart_devices[i].serial->parent.user_data = &s100_uart_devices[i]; - ret = rt_hw_serial_register(&s100_uarts[i].serial, - s100_uarts[i].name, + ret = rt_hw_serial_register(s100_uart_devices[i].serial, + s100_uart_devices[i].device_name, RT_DEVICE_FLAG_RDWR, - (void*)&s100_uarts[i]); + (void *)&s100_uart_devices[i]); if (ret != RT_EOK) { return ret; } - rt_hw_interrupt_install(s100_uarts[i].irqno,s100_uart_isr, &s100_uarts[i], s100_uarts[i].name); + rt_hw_interrupt_install(s100_uart_devices[i].irqno, + s100_uart_isr, + s100_uart_devices[i].serial, + s100_uart_devices[i].device_name); } return ret; } INIT_BOARD_EXPORT(rt_hw_uart_init); -#endif /* RT_USING_SERIAL_V2 */ +#endif /* RT_USING_SERIAL_V2 */ From df24f07a6c164b77d9f124deb4f2ec430b30478a Mon Sep 17 00:00:00 2001 From: rcitach Date: Wed, 22 Apr 2026 07:55:46 +0000 Subject: [PATCH 6/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=B9=B6=E5=AE=8C=E5=96=84=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/rdk/s100/README.md | 132 ++++++++++++++ bsp/rdk/s100/SConstruct | 2 +- bsp/rdk/s100/drivers/SConscript | 6 + bsp/rdk/s100/drivers/drv_uart_v2.c | 3 + bsp/rdk/s100/drivers/utest/SConscript | 16 ++ bsp/rdk/s100/drivers/utest/test_can.c | 227 ++++++++++++++++++++++++ bsp/rdk/s100/drivers/utest/test_gpio.c | 229 +++++++++++++++++++++++++ bsp/rdk/s100/drivers/utest/test_uart.c | 214 +++++++++++++++++++++++ bsp/rdk/s100/figure/device_test.png | Bin 0 -> 9953 bytes bsp/rdk/s100/figure/kernel_test.png | Bin 0 -> 25622 bytes 10 files changed, 828 insertions(+), 1 deletion(-) create mode 100644 bsp/rdk/s100/drivers/utest/SConscript create mode 100644 bsp/rdk/s100/drivers/utest/test_can.c create mode 100644 bsp/rdk/s100/drivers/utest/test_gpio.c create mode 100644 bsp/rdk/s100/drivers/utest/test_uart.c create mode 100644 bsp/rdk/s100/figure/device_test.png create mode 100644 bsp/rdk/s100/figure/kernel_test.png diff --git a/bsp/rdk/s100/README.md b/bsp/rdk/s100/README.md index e6bd2a1dbd1..f15b5c3bca2 100644 --- a/bsp/rdk/s100/README.md +++ b/bsp/rdk/s100/README.md @@ -152,3 +152,135 @@ echo start > state ```bash reboot ``` + +## 6. 系统支持外设说明 + +- 支持 UART 4、5、6(暂不支持DMA),默认使用串口4作为msh控制台 +- 支持GPIO输入、输出、外部中断响应功能,但以下引脚不允许被配置 + + ```shell + static const s100_pin_t s100_gpio_blacklist[] = + { + 0, /* S100 Power related pins */ + 5, /* S100 debug uart tx */ + 38, /* S100 Power related pins */ + 15, /* S100 Power related pins */ + 68, /* S100 Power related pins */ + 69, /* S100 Power related pins */ + 71, /* S100 Power related pins */ + 80, /* S100 Power related pins */ + 81, /* S100 Power related pins */ + 82, /* S100 Power related pins */ + 83, /* S100 Power related pins */ + AON_PIN_NUM(0), /* S100 debug uart rx */ + AON_PIN_NUM(12), /* S100 Power related pins */ + }; + ``` + +- 支持 CAN5、CAN6、CAN7、CAN8、CAN9(只支持基础CAN通信) + +## 7.测试方法 + +### 硬件连接 + +RDK S100 需要先连接 MCU 接口扩展版 + +### 软件配置 + +为了运行当前 `s100` BSP 下的 GPIO、UART、CAN 设备测试,建议至少打开以下配置。 + +#### 通用测试开关 + +使用 ` scons --menuconfig `打开配置界面 + +- 打开内核测试配置: + ![kernel_test](./figure/kernel_test.png) + +- 打开外设测试配置: + ![device_test](./figure/device_test.png) + +当前默认配置里,上述 `utest` 基础开关已经打开;如果你重新裁剪过配置,需确认这些选项仍然存在。 + +#### GPIO 测试相关配置 + +- 使能 `BSP_USING_GPIO`(默认已经打开) + +GPIO 测试文件为: + +- [test_gpio.c](./drivers/utest/test_gpio.c) + +当前测试内容包括: + +- 非法脚/保留脚拒绝逻辑 +- GPIO 输入输出回环 +- GPIO 中断上升沿、下降沿、双边沿回环 + +运行前要求: + +- 用跳线连接测试输出脚和测试输入脚 +- 默认测试脚为 `GPIO36 -> GPIO37` +- 若板级接线不同,可修改 `test_gpio.c` 中的 `S100_GPIO_TEST_OUT_PIN` 与 `S100_GPIO_TEST_IN_PIN` + +#### UART 测试相关配置 + +- 使能 `BSP_USING_UART` +- 保持 `BSP_USING_UART4=y` +- 额外使能至少一个非控制台串口: + - `BSP_USING_UART5` + - 或 `BSP_USING_UART6` + +UART 测试文件为: + +- [test_uart.c](./drivers/utest/test_uart.c) + +当前测试约束如下: + +- `uart4` 默认为 `msh` 控制台,不参与设备测试 +- 测试对象为已启用的 `uart5`、`uart6` +- `txrx` 用例发送固定二进制数据帧,并逐字节校验接收内容 + +运行前要求: + +- 被测串口需要具备回环条件 +- 常见做法是将 `UART5_TX` 与 `UART5_RX` 短接,或将 `UART6_TX` 与 `UART6_RX` 短接 +- 若未打开 `uart5/uart6`,`rdk.s100.drivers.uart` 不会覆盖非控制台串口 + +#### CAN 测试相关配置 + +- 使能 `BSP_USING_CAN` +- 使能至少一个 CAN 控制器: + - `BSP_USING_CAN5` + - `BSP_USING_CAN6` + - `BSP_USING_CAN7` + - `BSP_USING_CAN8` + - `BSP_USING_CAN9` + +CAN 测试文件为: + +- [test_can.c](./drivers/utest/test_can.c) + +当前测试特点如下: + +- 使用 `RT_CAN_MODE_LOOPBACK` 内部回环模式 +- 不依赖外部 CAN 对端 +- 覆盖 `find/open/config/set_mode/set_baud/write/read/get_status/close` +- 发送一帧标准 CAN 数据帧,并逐字节校验接收 payload + +#### 构建与运行 + +完成配置后重新编译: + +```bash +scons -j$(nproc) +``` + +板端启动后,可在 `msh` 中分别执行: + +```bash +utest_run rdk.s100.drivers.gpio +utest_run rdk.s100.drivers.uart +utest_run rdk.s100.drivers.can +``` + +如果只想执行单项测试,保留对应驱动开关即可;未启用的设备不会进入对应测试覆盖范围。 + diff --git a/bsp/rdk/s100/SConstruct b/bsp/rdk/s100/SConstruct index 022424e43ad..ab088a68f27 100644 --- a/bsp/rdk/s100/SConstruct +++ b/bsp/rdk/s100/SConstruct @@ -34,7 +34,7 @@ def _replace_cortex_r52_with_startup(objects): name for name in os.listdir(startup_dir) if os.path.isfile(os.path.join(startup_dir, name)) ) - cpu_dir = os.path.abspath(os.path.join(RTT_ROOT, 'libcpu', 'arm', 'cortex-r52')) + cpu_dir = os.path.abspath(os.path.join(RTT_ROOT, 'libcpu', rtconfig.ARCH, rtconfig.CPU)) def _source_path(node): for attr in ('srcnode', 'rfile'): diff --git a/bsp/rdk/s100/drivers/SConscript b/bsp/rdk/s100/drivers/SConscript index 6b308a4ed17..94ef7d142d3 100644 --- a/bsp/rdk/s100/drivers/SConscript +++ b/bsp/rdk/s100/drivers/SConscript @@ -1,6 +1,7 @@ from building import * cwd = GetCurrentDir() +list = os.listdir(cwd) src = [] src += ['drv_timer.c'] @@ -19,4 +20,9 @@ if GetDepend('BSP_USING_CAN'): objs = DefineGroup('drivers', src, depend=[''], CPPPATH=[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/rdk/s100/drivers/drv_uart_v2.c b/bsp/rdk/s100/drivers/drv_uart_v2.c index 5453e5039d3..f1ccc22084d 100644 --- a/bsp/rdk/s100/drivers/drv_uart_v2.c +++ b/bsp/rdk/s100/drivers/drv_uart_v2.c @@ -439,10 +439,12 @@ static rt_err_t s100_uart_configure(struct rt_serial_device *serial, { ret = s100_uart_set_baud(uart, cfg->baud_rate); } + if (ret == RT_EOK) { ret = s100_uart_set_lcr(uart, cfg); } + if (ret == RT_EOK) { s100_uart_set_fifo(uart); @@ -592,3 +594,4 @@ int rt_hw_uart_init(void) INIT_BOARD_EXPORT(rt_hw_uart_init); #endif /* RT_USING_SERIAL_V2 */ + diff --git a/bsp/rdk/s100/drivers/utest/SConscript b/bsp/rdk/s100/drivers/utest/SConscript new file mode 100644 index 00000000000..a59d57d951a --- /dev/null +++ b/bsp/rdk/s100/drivers/utest/SConscript @@ -0,0 +1,16 @@ +from building import * + +src = [] + +if GetDepend('BSP_USING_GPIO'): + src += ['test_gpio.c'] + +if GetDepend('BSP_USING_CAN5') or GetDepend('BSP_USING_CAN6') or GetDepend('BSP_USING_CAN7') or GetDepend('BSP_USING_CAN8') or GetDepend('BSP_USING_CAN9'): + src += ['test_can.c'] + +if GetDepend('BSP_USING_UART'): + src += ['test_uart.c'] + +group = DefineGroup('utestcases', src, depend = ['RT_UTEST_DRIVERS_CORE']) + +Return('group') diff --git a/bsp/rdk/s100/drivers/utest/test_can.c b/bsp/rdk/s100/drivers/utest/test_can.c new file mode 100644 index 00000000000..734c1a766aa --- /dev/null +++ b/bsp/rdk/s100/drivers/utest/test_can.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ + +#include +#include + +/* + * S100 CAN utest 说明 + * + * 1. 本测试面向当前 rdk/s100 BSP 的 RT-Thread CAN 设备驱动,覆盖设备发现、 + * open、配置、模式切换、发送、接收、状态读取和 close 的基础路径。 + * 2. 为避免依赖外部 CAN 对端,本测试使用驱动支持的 RT_CAN_MODE_LOOPBACK 内部回环模式。 + * 因此测试默认不要求外部收发器回环或两节点组网。 + * 3. 测试对象仅包含当前配置中启用的 can5/can6/can7/can8/can9。 + * 4. 发送内容使用一帧标准数据帧(11-bit ID,8 字节 payload),接收后逐字段校验: + * - IDE/RTR + * - 标准 ID + * - DLC + * - data[0..7] + * 5. 若需要改成外部总线联调,请把 loopback 模式切回 normal,并去掉本用例的回环假设。 + */ + +static const struct rt_can_msg s100_can_test_msg = +{ + .id = 0x123, + .ide = RT_CAN_STDID, + .rtr = RT_CAN_DTR, + .len = 8, + .priv = 0, + .hdr_index = -1, + .rxfifo = 0, + .reserved = 0, + .nonblocking = 0, + .data = {0x55, 0xAA, 0x00, 0xFF, 0x11, 0x22, 0x33, 0x44}, +}; + +struct s100_can_test_port +{ + const char *name; +}; + +#if defined(BSP_USING_CAN5) || defined(BSP_USING_CAN6) || defined(BSP_USING_CAN7) || defined(BSP_USING_CAN8) || defined(BSP_USING_CAN9) +static const struct s100_can_test_port s100_can_test_ports[] = +{ +#ifdef BSP_USING_CAN5 + { "can5" }, +#endif +#ifdef BSP_USING_CAN6 + { "can6" }, +#endif +#ifdef BSP_USING_CAN7 + { "can7" }, +#endif +#ifdef BSP_USING_CAN8 + { "can8" }, +#endif +#ifdef BSP_USING_CAN9 + { "can9" }, +#endif +}; + +#define S100_CAN_TEST_PORT_COUNT \ + (sizeof(s100_can_test_ports) / sizeof(s100_can_test_ports[0])) +#else +static const struct s100_can_test_port s100_can_test_ports[] = +{ + { RT_NULL }, +}; + +#define S100_CAN_TEST_PORT_COUNT 0u +#endif + +static void s100_can_prepare_config(struct can_configure *cfg) +{ + RT_ASSERT(cfg != RT_NULL); + + cfg->baud_rate = CAN1MBaud; + cfg->mode = RT_CAN_MODE_LOOPBACK; + cfg->privmode = RT_CAN_MODE_NOPRIV; +} + +static void s100_can_check_port_basic(const char *name) +{ + rt_device_t can_dev; + struct can_configure cfg = CANDEFAULTCONFIG; + struct rt_can_status status; + rt_err_t ret; + + can_dev = rt_device_find(name); + uassert_not_null(can_dev); + + s100_can_prepare_config(&cfg); + + ret = rt_device_control(can_dev, RT_DEVICE_CTRL_CONFIG, &cfg); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_control(can_dev, RT_CAN_CMD_SET_MODE, (void *)RT_CAN_MODE_LOOPBACK); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_control(can_dev, RT_CAN_CMD_SET_BAUD, (void *)CAN1MBaud); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_control(can_dev, RT_CAN_CMD_GET_STATUS, &status); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_close(can_dev); + uassert_int_equal(ret, RT_EOK); +} + +static void s100_can_check_port_loopback(const char *name) +{ + rt_device_t can_dev; + struct can_configure cfg = CANDEFAULTCONFIG; + struct rt_can_msg rx_msg; + rt_err_t ret; + rt_ssize_t wr_len; + rt_ssize_t rd_len; + rt_size_t i; + + can_dev = rt_device_find(name); + uassert_not_null(can_dev); + + s100_can_prepare_config(&cfg); + + ret = rt_device_control(can_dev, RT_DEVICE_CTRL_CONFIG, &cfg); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_control(can_dev, RT_CAN_CMD_SET_MODE, (void *)RT_CAN_MODE_LOOPBACK); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_control(can_dev, RT_CAN_CMD_SET_BAUD, (void *)CAN1MBaud); + uassert_int_equal(ret, RT_EOK); + + rt_memset(&rx_msg, 0, sizeof(rx_msg)); + + rt_kprintf("%s tx can id=0x%03X len=%d\n", name, (unsigned int)s100_can_test_msg.id, (int)s100_can_test_msg.len); + LOG_HEX("can.tx", 16, s100_can_test_msg.data, s100_can_test_msg.len); + + wr_len = rt_device_write(can_dev, 0, &s100_can_test_msg, sizeof(s100_can_test_msg)); + uassert_int_equal((int)wr_len, (int)sizeof(s100_can_test_msg)); + + rd_len = rt_device_read(can_dev, 0, &rx_msg, sizeof(rx_msg)); + uassert_int_equal((int)rd_len, (int)sizeof(rx_msg)); + + rt_kprintf("%s rx can id=0x%03X len=%d\n", name, (unsigned int)rx_msg.id, (int)rx_msg.len); + LOG_HEX("can.rx", 16, rx_msg.data, rx_msg.len); + + uassert_int_equal((int)rx_msg.ide, (int)s100_can_test_msg.ide); + uassert_int_equal((int)rx_msg.rtr, (int)s100_can_test_msg.rtr); + uassert_int_equal((int)rx_msg.id, (int)s100_can_test_msg.id); + uassert_int_equal((int)rx_msg.len, (int)s100_can_test_msg.len); + + for (i = 0; i < s100_can_test_msg.len; i++) + { + rt_kprintf("%s compare[%d]: tx=0x%02X rx=0x%02X\n", + name, + (int)i, + s100_can_test_msg.data[i], + rx_msg.data[i]); + uassert_int_equal((int)rx_msg.data[i], (int)s100_can_test_msg.data[i]); + } + + ret = rt_device_close(can_dev); + uassert_int_equal(ret, RT_EOK); +} + +static void can_basic_demo(void) +{ + rt_size_t i; + + if (S100_CAN_TEST_PORT_COUNT == 0) + { + return; + } + + for (i = 0; i < S100_CAN_TEST_PORT_COUNT; i++) + { + s100_can_check_port_basic(s100_can_test_ports[i].name); + } +} + +static void can_loopback_demo(void) +{ + rt_size_t i; + + if (S100_CAN_TEST_PORT_COUNT == 0) + { + return; + } + + for (i = 0; i < S100_CAN_TEST_PORT_COUNT; i++) + { + s100_can_check_port_loopback(s100_can_test_ports[i].name); + } +} + +static void can_testcase(void) +{ + UTEST_UNIT_RUN(can_basic_demo); + UTEST_UNIT_RUN(can_loopback_demo); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +UTEST_TC_EXPORT(can_testcase, "rdk.s100.drivers.can", utest_tc_init, utest_tc_cleanup, 20); + diff --git a/bsp/rdk/s100/drivers/utest/test_gpio.c b/bsp/rdk/s100/drivers/utest/test_gpio.c new file mode 100644 index 00000000000..ba09b7192f0 --- /dev/null +++ b/bsp/rdk/s100/drivers/utest/test_gpio.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ +#include +#include + +#include "drv_gpio.h" +#include "drv_pinmux.h" + +/* + * S100 GPIO utest 说明 + * + * 1. 本文件合并了原先独立的 GPIO 基础功能测试和 GPIO IRQ 测试,统一面向当前 + * rdk/s100 BSP 的 RT-Thread pin 驱动接口。 + * 2. 测试维度按驱动能力组织: + * - driver basic:校验 s100 私有驱动对非法/保留 pin 的拒绝逻辑; + * - pin io loopback:校验 rt_pin_mode/write/read 基础输入输出路径; + * - pin irq loopback:校验 rt_pin_attach_irq/irq_enable 在上升沿、下降沿、 + * 双边沿模式下的中断分发行为。 + * 3. 为了避免依赖旧板级 LED/KEY 资源,IO/IRQ 测试采用“一个输出脚 + 一个输入脚” + * 的跳线回环方式。运行前请用杜邦线连接测试输出脚和测试输入脚。 + * 4. 默认使用 GPIO36 作为输出、GPIO37 作为输入;它们在当前 s100 驱动的黑名单和 + * 空洞编号之外。若板级接线需要变更,可在编译时覆盖下面两个宏。 + * 5. IRQ 测试通过切换输出脚电平来触发输入脚中断,因此不需要人工按键操作。 + */ + +#ifndef S100_GPIO_TEST_OUT_PIN +#define S100_GPIO_TEST_OUT_PIN 36 +#endif + +#ifndef S100_GPIO_TEST_IN_PIN +#define S100_GPIO_TEST_IN_PIN 37 +#endif + +#define S100_GPIO_INVALID_PIN 79 +#define S100_GPIO_RESERVED_PIN 0 +#define S100_GPIO_SETTLE_DELAY_MS 2 +#define S100_GPIO_IRQ_TIMEOUT_TICKS (RT_TICK_PER_SECOND / 2) + +static struct rt_completion s100_gpio_irq_completion; +static volatile rt_uint32_t s100_gpio_irq_count; + +static void s100_gpio_irq_handler(void *args) +{ + RT_UNUSED(args); + s100_gpio_irq_count++; + rt_completion_done(&s100_gpio_irq_completion); +} + +static void s100_gpio_prepare_loopback(void) +{ + uassert_true(s100_pin_is_valid(S100_GPIO_TEST_OUT_PIN) == RT_TRUE); + uassert_true(s100_pin_is_valid(S100_GPIO_TEST_IN_PIN) == RT_TRUE); + uassert_true(S100_GPIO_TEST_OUT_PIN != S100_GPIO_TEST_IN_PIN); + + rt_pin_mode(S100_GPIO_TEST_OUT_PIN, PIN_MODE_OUTPUT); + rt_pin_mode(S100_GPIO_TEST_IN_PIN, PIN_MODE_INPUT); + + rt_pin_write(S100_GPIO_TEST_OUT_PIN, PIN_LOW); + rt_thread_mdelay(S100_GPIO_SETTLE_DELAY_MS); +} + +static void s100_gpio_cleanup_irq(rt_base_t pin) +{ + rt_err_t ret; + + ret = rt_pin_irq_enable(pin, PIN_IRQ_DISABLE); + uassert_int_equal(ret, RT_EOK); + + ret = rt_pin_detach_irq(pin); + uassert_int_equal(ret, RT_EOK); +} + +static void s100_gpio_wait_irq_once(void) +{ + rt_err_t ret; + + ret = rt_completion_wait(&s100_gpio_irq_completion, S100_GPIO_IRQ_TIMEOUT_TICKS); + uassert_int_equal(ret, RT_EOK); +} + +static void s100_gpio_trigger_rising(void) +{ + rt_pin_write(S100_GPIO_TEST_OUT_PIN, PIN_LOW); + rt_thread_mdelay(S100_GPIO_SETTLE_DELAY_MS); + rt_pin_write(S100_GPIO_TEST_OUT_PIN, PIN_HIGH); +} + +static void s100_gpio_trigger_falling(void) +{ + rt_pin_write(S100_GPIO_TEST_OUT_PIN, PIN_HIGH); + rt_thread_mdelay(S100_GPIO_SETTLE_DELAY_MS); + rt_pin_write(S100_GPIO_TEST_OUT_PIN, PIN_LOW); +} + +static void gpio_driver_rejects_invalid_pins(void) +{ + rt_err_t ret; + + uassert_true(s100_pin_is_valid(S100_GPIO_INVALID_PIN) == RT_FALSE); + uassert_true(s100_pin_is_valid(S100_GPIO_RESERVED_PIN) == RT_FALSE); + + ret = s100_gpio_set_direction(S100_GPIO_INVALID_PIN, S100_PIN_DIR_OUT); + uassert_int_equal(ret, -RT_EINVAL); + + ret = s100_gpio_write_pin(S100_GPIO_INVALID_PIN, S100_PIN_LEVEL_HIGH); + uassert_int_equal(ret, -RT_EINVAL); + + ret = s100_gpio_set_direction(S100_GPIO_RESERVED_PIN, S100_PIN_DIR_OUT); + uassert_int_equal(ret, -RT_EINVAL); +} + +static void gpio_loopback_io(void) +{ + rt_ssize_t level; + + s100_gpio_prepare_loopback(); + + rt_pin_write(S100_GPIO_TEST_OUT_PIN, PIN_LOW); + rt_thread_mdelay(S100_GPIO_SETTLE_DELAY_MS); + level = rt_pin_read(S100_GPIO_TEST_IN_PIN); + uassert_int_equal(level, PIN_LOW); + + rt_pin_write(S100_GPIO_TEST_OUT_PIN, PIN_HIGH); + rt_thread_mdelay(S100_GPIO_SETTLE_DELAY_MS); + level = rt_pin_read(S100_GPIO_TEST_IN_PIN); + uassert_int_equal(level, PIN_HIGH); + + rt_pin_write(S100_GPIO_TEST_OUT_PIN, PIN_LOW); +} + +static void gpio_irq_rising_loopback(void) +{ + rt_err_t ret; + + s100_gpio_prepare_loopback(); + rt_completion_init(&s100_gpio_irq_completion); + s100_gpio_irq_count = 0; + + ret = rt_pin_attach_irq(S100_GPIO_TEST_IN_PIN, PIN_IRQ_MODE_RISING, + s100_gpio_irq_handler, RT_NULL); + uassert_int_equal(ret, RT_EOK); + + ret = rt_pin_irq_enable(S100_GPIO_TEST_IN_PIN, PIN_IRQ_ENABLE); + uassert_int_equal(ret, RT_EOK); + + s100_gpio_trigger_rising(); + s100_gpio_wait_irq_once(); + uassert_int_equal((int)s100_gpio_irq_count, 1); + + s100_gpio_cleanup_irq(S100_GPIO_TEST_IN_PIN); +} + +static void gpio_irq_falling_loopback(void) +{ + rt_err_t ret; + + s100_gpio_prepare_loopback(); + rt_completion_init(&s100_gpio_irq_completion); + s100_gpio_irq_count = 0; + + ret = rt_pin_attach_irq(S100_GPIO_TEST_IN_PIN, PIN_IRQ_MODE_FALLING, + s100_gpio_irq_handler, RT_NULL); + uassert_int_equal(ret, RT_EOK); + + ret = rt_pin_irq_enable(S100_GPIO_TEST_IN_PIN, PIN_IRQ_ENABLE); + uassert_int_equal(ret, RT_EOK); + + s100_gpio_trigger_falling(); + s100_gpio_wait_irq_once(); + uassert_int_equal((int)s100_gpio_irq_count, 1); + + s100_gpio_cleanup_irq(S100_GPIO_TEST_IN_PIN); +} + +static void gpio_irq_both_edge_loopback(void) +{ + rt_err_t ret; + + s100_gpio_prepare_loopback(); + rt_completion_init(&s100_gpio_irq_completion); + s100_gpio_irq_count = 0; + + ret = rt_pin_attach_irq(S100_GPIO_TEST_IN_PIN, PIN_IRQ_MODE_RISING_FALLING, + s100_gpio_irq_handler, RT_NULL); + uassert_int_equal(ret, RT_EOK); + + ret = rt_pin_irq_enable(S100_GPIO_TEST_IN_PIN, PIN_IRQ_ENABLE); + uassert_int_equal(ret, RT_EOK); + + s100_gpio_trigger_rising(); + s100_gpio_wait_irq_once(); + + rt_completion_init(&s100_gpio_irq_completion); + s100_gpio_trigger_falling(); + s100_gpio_wait_irq_once(); + + uassert_int_equal((int)s100_gpio_irq_count, 2); + + s100_gpio_cleanup_irq(S100_GPIO_TEST_IN_PIN); +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(gpio_driver_rejects_invalid_pins); + UTEST_UNIT_RUN(gpio_loopback_io); + UTEST_UNIT_RUN(gpio_irq_rising_loopback); + UTEST_UNIT_RUN(gpio_irq_falling_loopback); + UTEST_UNIT_RUN(gpio_irq_both_edge_loopback); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +UTEST_TC_EXPORT(testcase, "rdk.s100.drivers.gpio", utest_tc_init, utest_tc_cleanup, 20); + diff --git a/bsp/rdk/s100/drivers/utest/test_uart.c b/bsp/rdk/s100/drivers/utest/test_uart.c new file mode 100644 index 00000000000..c89540e33f3 --- /dev/null +++ b/bsp/rdk/s100/drivers/utest/test_uart.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-04-20 rcitach first version + */ + +#include +#include +#include + +/* + * S100 UART utest 说明 + * + * 1. 本测试面向当前 BSP 的 UART v2 驱动实现,覆盖非控制台串口的基础访问流程。 + * 2. 根据 BSP 约定,uart4 默认为 msh 控制台,本测试不会对 uart4 做 open/read/write + * 覆盖,避免干扰交互终端。 + * 3. 测试对象仅包含启用的 uart5 和 uart6;若两者都未使能,测试会打印跳过提示。 + * 4. 测试分为两部分: + * - basic:验证 rt_device_find/open/control(close) 这条基础控制路径; + * - txrx smoke:验证配置成功后能够执行一次 write,并检查 read 接口可调用。 + * 5. 当前 S100 UART BSP 不支持 DMA,因此这里不覆盖 DMA 模式。 + * 6. txrx smoke 现在要求被测串口具备回环条件(硬件短接 TX/RX 或外部回环),测试会校验 + * 接收到的数据内容与发送 payload 完全一致。 + */ + +#define S100_UART_TEST_BAUD_RATE 115200 +#define S100_UART_READ_BUF_SIZE 16 +#define S100_UART_RX_TIMEOUT_TICKS (RT_TICK_PER_SECOND / 2) + +static const rt_uint8_t s100_uart_test_frame[] = +{ + 0x55, 0xAA, 0x00, 0xFF, 0x31, 0x32, 0x33, 0x0D, 0x0A, +}; + +struct s100_uart_test_port +{ + const char *name; +}; + +#if defined(BSP_USING_UART5) || defined(BSP_USING_UART6) +static const struct s100_uart_test_port s100_uart_test_ports[] = +{ +#ifdef BSP_USING_UART5 + { "uart5" }, +#endif +#ifdef BSP_USING_UART6 + { "uart6" }, +#endif +}; + +#define S100_UART_TEST_PORT_COUNT \ + (sizeof(s100_uart_test_ports) / sizeof(s100_uart_test_ports[0])) +#else +static const struct s100_uart_test_port s100_uart_test_ports[] = +{ + { RT_NULL }, +}; + +#define S100_UART_TEST_PORT_COUNT 0u +#endif + +static void s100_uart_prepare_config(struct serial_configure *config) +{ + RT_ASSERT(config != RT_NULL); + + config->baud_rate = S100_UART_TEST_BAUD_RATE; + config->data_bits = DATA_BITS_8; + config->stop_bits = STOP_BITS_1; + config->parity = PARITY_NONE; + config->flowcontrol = RT_SERIAL_FLOWCONTROL_NONE; +} + +static void s100_uart_check_port_basic(const char *name) +{ + rt_device_t uart_dev; + struct serial_configure config; + rt_err_t ret; + + uart_dev = rt_device_find(name); + uassert_not_null(uart_dev); + + ret = rt_device_control(uart_dev, RT_SERIAL_CTRL_GET_CONFIG, &config); + uassert_int_equal(ret, RT_EOK); + + s100_uart_prepare_config(&config); + + ret = rt_device_open(uart_dev, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_control(uart_dev, RT_DEVICE_CTRL_CONFIG, &config); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_close(uart_dev); + uassert_int_equal(ret, RT_EOK); +} + +static void s100_uart_check_port_txrx_smoke(const char *name) +{ + rt_uint8_t rx_buf[sizeof(s100_uart_test_frame)]; + rt_device_t uart_dev; + struct serial_configure config; + rt_err_t ret; + rt_ssize_t len; + rt_size_t rx_total; + rt_size_t i; + rt_tick_t deadline; + + uart_dev = rt_device_find(name); + uassert_not_null(uart_dev); + + ret = rt_device_control(uart_dev, RT_SERIAL_CTRL_GET_CONFIG, &config); + uassert_int_equal(ret, RT_EOK); + + s100_uart_prepare_config(&config); + + ret = rt_device_open(uart_dev, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX); + uassert_int_equal(ret, RT_EOK); + + ret = rt_device_control(uart_dev, RT_DEVICE_CTRL_CONFIG, &config); + uassert_int_equal(ret, RT_EOK); + + LOG_HEX("uart.tx", 16, s100_uart_test_frame, sizeof(s100_uart_test_frame)); + len = rt_device_write(uart_dev, 0, s100_uart_test_frame, sizeof(s100_uart_test_frame)); + uassert_int_equal(len, (rt_ssize_t)sizeof(s100_uart_test_frame)); + + rx_total = 0; + deadline = rt_tick_get() + S100_UART_RX_TIMEOUT_TICKS; + while ((rx_total < sizeof(s100_uart_test_frame)) && (rt_tick_get() < deadline)) + { + len = rt_device_read(uart_dev, 0, rx_buf + rx_total, sizeof(s100_uart_test_frame) - rx_total); + uassert_true(len >= 0); + + if (len == 0) + { + rt_thread_mdelay(10); + continue; + } + + LOG_HEX("uart.rx.chunk", 16, rx_buf + rx_total, (rt_size_t)len); + rx_total += (rt_size_t)len; + } + + if (rx_total > 0) + { + LOG_HEX("uart.rx.total", 16, rx_buf, rx_total); + } + + uassert_int_equal((int)rx_total, (int)sizeof(s100_uart_test_frame)); + for (i = 0; i < sizeof(s100_uart_test_frame); i++) + { + rt_kprintf("%s compare[%d]: tx=0x%02X rx=0x%02X\n", + name, + (int)i, + s100_uart_test_frame[i], + rx_buf[i]); + uassert_int_equal((int)rx_buf[i], (int)s100_uart_test_frame[i]); + } + + ret = rt_device_close(uart_dev); + uassert_int_equal(ret, RT_EOK); +} + +static void uart_non_console_basic_demo(void) +{ + rt_size_t i; + + if (S100_UART_TEST_PORT_COUNT == 0) + { + return; + } + + for (i = 0; i < S100_UART_TEST_PORT_COUNT; i++) + { + s100_uart_check_port_basic(s100_uart_test_ports[i].name); + } +} + +static void uart_non_console_txrx_demo(void) +{ + rt_size_t i; + + if (S100_UART_TEST_PORT_COUNT == 0) + { + return; + } + + for (i = 0; i < S100_UART_TEST_PORT_COUNT; i++) + { + s100_uart_check_port_txrx_smoke(s100_uart_test_ports[i].name); + } +} + +static void uart_testcase(void) +{ + UTEST_UNIT_RUN(uart_non_console_basic_demo); + UTEST_UNIT_RUN(uart_non_console_txrx_demo); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +UTEST_TC_EXPORT(uart_testcase, "rdk.s100.drivers.uart", utest_tc_init, utest_tc_cleanup, 10); + diff --git a/bsp/rdk/s100/figure/device_test.png b/bsp/rdk/s100/figure/device_test.png new file mode 100644 index 0000000000000000000000000000000000000000..fb2b86f35847349d81170001b33b6d07aafb3fef GIT binary patch literal 9953 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 A>;M1& literal 0 HcmV?d00001 diff --git a/bsp/rdk/s100/figure/kernel_test.png b/bsp/rdk/s100/figure/kernel_test.png new file mode 100644 index 0000000000000000000000000000000000000000..9c45b5665955b01673f6a37223fb63198d10f2f8 GIT binary patch literal 25622 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

mI@w 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 HsptED2qs8c literal 0 HcmV?d00001