diff --git a/bsp/at32/at32f403a-start/rtconfig.py b/bsp/at32/at32f403a-start/rtconfig.py index 5f2f01ca7605cfd1571b98bdd984d064f87df5bb..8e78aa373b8bdfc48835004e76afde7be55f2af4 100644 --- a/bsp/at32/at32f403a-start/rtconfig.py +++ b/bsp/at32/at32f403a-start/rtconfig.py @@ -1,5 +1,4 @@ import os -import sys # toolchains options ARCH='arm' @@ -143,8 +142,9 @@ elif PLATFORM == 'iar': EXEC_PATH = EXEC_PATH + '/arm/bin/' POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' -def dist_handle(BSP_ROOT): +def dist_handle(BSP_ROOT, dist_dir): + import sys cwd_path = os.getcwd() sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) from sdk_dist import dist_do_building - dist_do_building(BSP_ROOT) + dist_do_building(BSP_ROOT, dist_dir) diff --git a/bsp/at32/at32f407-start/rtconfig.py b/bsp/at32/at32f407-start/rtconfig.py index 1d63cabb9675201230fdce7f9238a30c4b12aa80..0749f7ecb0562949cb5f86cec6cf4543f7ed3b3f 100644 --- a/bsp/at32/at32f407-start/rtconfig.py +++ b/bsp/at32/at32f407-start/rtconfig.py @@ -141,3 +141,10 @@ elif PLATFORM == 'iar': EXEC_PATH = EXEC_PATH + '/arm/bin/' POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' + +def dist_handle(BSP_ROOT, dist_dir): + import sys + cwd_path = os.getcwd() + sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) + from sdk_dist import dist_do_building + dist_do_building(BSP_ROOT, dist_dir) diff --git a/bsp/at32/tools/sdk_dist.py b/bsp/at32/tools/sdk_dist.py index 01ff930b20001254a6f448ae4b95748a3b3ad43a..4c36c9b6e318dc10613e60b6e3e8b3b0096d88a9 100644 --- a/bsp/at32/tools/sdk_dist.py +++ b/bsp/at32/tools/sdk_dist.py @@ -5,15 +5,16 @@ cwd_path = os.getcwd() sys.path.append(os.path.join(os.path.dirname(cwd_path), 'rt-thread', 'tools')) # BSP dist function -def dist_do_building(BSP_ROOT): +def dist_do_building(BSP_ROOT, dist_dir): from mkdist import bsp_copy_files import rtconfig - - dist_dir = os.path.join(BSP_ROOT, 'dist', os.path.basename(BSP_ROOT)) + + print("=> copy at32 bsp library") + library_dir = os.path.join(dist_dir, 'Libraries') library_path = os.path.join(os.path.dirname(BSP_ROOT), 'Libraries') - library_dir = os.path.join(dist_dir, 'Libraries') + bsp_copy_files(os.path.join(library_path, rtconfig.BSP_LIBRARY_TYPE), + os.path.join(library_dir, rtconfig.BSP_LIBRARY_TYPE)) + print("=> copy bsp drivers") bsp_copy_files(os.path.join(library_path, 'rt_drivers'), os.path.join(library_dir, 'rt_drivers')) - print("=> copy bsp library") - bsp_copy_files(os.path.join(library_path, rtconfig.BSP_LIBRARY_TYPE), os.path.join(library_dir, rtconfig.BSP_LIBRARY_TYPE)) shutil.copyfile(os.path.join(library_path, 'Kconfig'), os.path.join(library_dir, 'Kconfig')) diff --git a/bsp/imxrt/imxrt1052-atk-commander/rtconfig.py b/bsp/imxrt/imxrt1052-atk-commander/rtconfig.py index 9b0c3da87f95c0c72b0ae7f3f75746fb2a3e8544..cf79de685ad42cd39e3ec85a4dcc62c3cd7a1d69 100644 --- a/bsp/imxrt/imxrt1052-atk-commander/rtconfig.py +++ b/bsp/imxrt/imxrt1052-atk-commander/rtconfig.py @@ -6,6 +6,9 @@ ARCH='arm' CPU='cortex-m7' CROSS_TOOL='gcc' +# bsp lib config +BSP_LIBRARY_TYPE = None + if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') if os.getenv('RTT_ROOT'): @@ -149,9 +152,11 @@ elif PLATFORM == 'iar': EXEC_PATH = EXEC_PATH + '/arm/bin/' POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' -def dist_handle(BSP_ROOT): + +def dist_handle(BSP_ROOT, dist_dir): + import sys cwd_path = os.getcwd() sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) from sdk_dist import dist_do_building - dist_do_building(BSP_ROOT) + dist_do_building(BSP_ROOT, dist_dir) \ No newline at end of file diff --git a/bsp/imxrt/imxrt1052-fire-pro/rtconfig.py b/bsp/imxrt/imxrt1052-fire-pro/rtconfig.py index 9b0c3da87f95c0c72b0ae7f3f75746fb2a3e8544..552cefe8356221b4b14d04600de755d5b4337b80 100644 --- a/bsp/imxrt/imxrt1052-fire-pro/rtconfig.py +++ b/bsp/imxrt/imxrt1052-fire-pro/rtconfig.py @@ -6,6 +6,9 @@ ARCH='arm' CPU='cortex-m7' CROSS_TOOL='gcc' +# bsp lib config +BSP_LIBRARY_TYPE = None + if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') if os.getenv('RTT_ROOT'): @@ -149,9 +152,11 @@ elif PLATFORM == 'iar': EXEC_PATH = EXEC_PATH + '/arm/bin/' POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' -def dist_handle(BSP_ROOT): +def dist_handle(BSP_ROOT, dist_dir): + import sys cwd_path = os.getcwd() sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) from sdk_dist import dist_do_building - dist_do_building(BSP_ROOT) + dist_do_building(BSP_ROOT, dist_dir) + \ No newline at end of file diff --git a/bsp/imxrt/imxrt1052-nxp-evk/rtconfig.py b/bsp/imxrt/imxrt1052-nxp-evk/rtconfig.py index 88fd75b5e69f73d2e052383f41dd8f014beae647..44de4dc1dff582dfa99b679259cce07726a5a4e7 100644 --- a/bsp/imxrt/imxrt1052-nxp-evk/rtconfig.py +++ b/bsp/imxrt/imxrt1052-nxp-evk/rtconfig.py @@ -6,6 +6,9 @@ ARCH='arm' CPU='cortex-m7' CROSS_TOOL='gcc' +# bsp lib config +BSP_LIBRARY_TYPE = None + if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') if os.getenv('RTT_ROOT'): @@ -149,9 +152,10 @@ elif PLATFORM == 'iar': EXEC_PATH = EXEC_PATH + '/arm/bin/' POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' -def dist_handle(BSP_ROOT): +def dist_handle(BSP_ROOT, dist_dir): + import sys cwd_path = os.getcwd() sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) from sdk_dist import dist_do_building - dist_do_building(BSP_ROOT) + dist_do_building(BSP_ROOT, dist_dir) \ No newline at end of file diff --git a/bsp/imxrt/imxrt1064-nxp-evk/SConstruct b/bsp/imxrt/imxrt1064-nxp-evk/SConstruct index 71be0c13c696ff3a28229fc4121020a44c1ae381..2827f048f0ac0c9121859cc9f38264d1220a1b67 100644 --- a/bsp/imxrt/imxrt1064-nxp-evk/SConstruct +++ b/bsp/imxrt/imxrt1064-nxp-evk/SConstruct @@ -45,11 +45,26 @@ if rtconfig.PLATFORM == 'iar': Export('RTT_ROOT') Export('rtconfig') +SDK_ROOT = os.path.abspath('./') +if os.path.exists(SDK_ROOT + '/Libraries'): + libraries_path_prefix = SDK_ROOT + '/Libraries' +else: + libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/Libraries' + +SDK_LIB = libraries_path_prefix +Export('SDK_LIB') + # prepare building environment objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) -objs = objs + SConscript('../libraries/drivers/SConscript') -objs = objs + SConscript('../libraries/MIMXRT1064/SConscript') +imxrt_library = 'MIMXRT1064' +rtconfig.BSP_LIBRARY_TYPE = imxrt_library + +# include libraries +objs.extend(SConscript(os.path.join(libraries_path_prefix, imxrt_library, 'SConscript'))) + +# include drivers +objs.extend(SConscript(os.path.join(libraries_path_prefix, 'drivers', 'SConscript'))) # make a building DoBuilding(TARGET, objs) diff --git a/bsp/imxrt/imxrt1064-nxp-evk/rtconfig.py b/bsp/imxrt/imxrt1064-nxp-evk/rtconfig.py index 4eccbc92fd5be740326538fd2eeeec7bb17b0778..2acb77e3edc5f26142348dd9a806ca692c42bc15 100644 --- a/bsp/imxrt/imxrt1064-nxp-evk/rtconfig.py +++ b/bsp/imxrt/imxrt1064-nxp-evk/rtconfig.py @@ -5,6 +5,9 @@ ARCH='arm' CPU='cortex-m7' CROSS_TOOL='gcc' +# bsp lib config +BSP_LIBRARY_TYPE = None + if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') if os.getenv('RTT_ROOT'): @@ -150,3 +153,10 @@ elif PLATFORM == 'iar': EXEC_PATH = EXEC_PATH + '/arm/bin/' POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' + +def dist_handle(BSP_ROOT, dist_dir): + import sys + cwd_path = os.getcwd() + sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) + from sdk_dist import dist_do_building + dist_do_building(BSP_ROOT, dist_dir) diff --git a/bsp/imxrt/tools/sdk_dist.py b/bsp/imxrt/tools/sdk_dist.py index ebf869b689a72416a3086c795cf59df1e4a338c4..89b7da4356d9d1354cc16d70db3d8ea9458239e9 100644 --- a/bsp/imxrt/tools/sdk_dist.py +++ b/bsp/imxrt/tools/sdk_dist.py @@ -5,15 +5,19 @@ cwd_path = os.getcwd() sys.path.append(os.path.join(os.path.dirname(cwd_path), 'rt-thread', 'tools')) # BSP dist function -def dist_do_building(BSP_ROOT): +def dist_do_building(BSP_ROOT, dist_dir=None): from mkdist import bsp_copy_files import rtconfig - dist_dir = os.path.join(BSP_ROOT, 'dist', os.path.basename(BSP_ROOT)) + if dist_dir is None: + dist_dir = os.path.join(BSP_ROOT, 'dist', os.path.basename(BSP_ROOT)) + + print("=> copy imxrt bsp library") library_path = os.path.join(os.path.dirname(BSP_ROOT), 'libraries') library_dir = os.path.join(dist_dir, 'libraries') + bsp_copy_files(os.path.join(library_path, rtconfig.BSP_LIBRARY_TYPE), + os.path.join(library_dir, rtconfig.BSP_LIBRARY_TYPE)) + print("=> copy bsp drivers") bsp_copy_files(os.path.join(library_path, 'drivers'), os.path.join(library_dir, 'drivers')) - print("=> copy bsp library") - bsp_copy_files(os.path.join(library_path, rtconfig.BSP_LIBRARY_TYPE), os.path.join(library_dir, rtconfig.BSP_LIBRARY_TYPE)) shutil.copyfile(os.path.join(library_path, 'Kconfig'), os.path.join(library_dir, 'Kconfig')) diff --git a/bsp/ls2kdev/.config b/bsp/ls2kdev/.config index d8a97b46b066727a089b78e5f0ce7a2428ab4e1f..e841744dfc22b9aec4ed222372d2676f4ef6b224 100644 --- a/bsp/ls2kdev/.config +++ b/bsp/ls2kdev/.config @@ -9,7 +9,7 @@ CONFIG_RT_NAME_MAX=8 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_SMP is not set -CONFIG_RT_ALIGN_SIZE=4 +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 @@ -203,6 +203,8 @@ CONFIG_RT_USING_LIBC=y # 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_CJSON is not set # CONFIG_PKG_USING_JSMN is not set @@ -229,6 +231,7 @@ CONFIG_RT_USING_LIBC=y # 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 @@ -243,6 +246,8 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_AZURE is not set # CONFIG_PKG_USING_TENCENT_IOTHUB 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_NIMBLE is not set # CONFIG_PKG_USING_OTA_DOWNLOADER is not set # CONFIG_PKG_USING_IPMSG is not set @@ -257,6 +262,10 @@ CONFIG_RT_USING_LIBC=y # 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_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set # # security packages @@ -264,6 +273,7 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_MBEDTLS is not set # CONFIG_PKG_USING_libsodium is not set # CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set # # language packages @@ -298,6 +308,7 @@ CONFIG_RT_USING_LIBC=y # 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_URLENCODE is not set # # system packages @@ -317,6 +328,9 @@ CONFIG_RT_USING_LIBC=y # 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 # # peripheral libraries and drivers @@ -333,6 +347,10 @@ CONFIG_RT_USING_LIBC=y # 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_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set # CONFIG_PKG_USING_WM_LIBRARIES is not set # CONFIG_PKG_USING_KENDRYTE_SDK is not set # CONFIG_PKG_USING_INFRARED is not set @@ -349,6 +367,14 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_MAX17048 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_EMBARC_BSP 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 # # miscellaneous packages @@ -410,9 +436,11 @@ CONFIG_RT_USING_LIBC=y # CONFIG_RT_USING_TESTCASE is not set # CONFIG_PKG_USING_NGHTTP2 is not set # CONFIG_PKG_USING_AVS is not set -# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_ALI_LINKKIT is not set # CONFIG_PKG_USING_STS is not set # CONFIG_PKG_USING_DLMS is not set # CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set # CONFIG_PKG_USING_ZBAR is not set +# CONFIG_PKG_USING_MCF is not set +# CONFIG_PKG_USING_URPC is not set CONFIG_SOC_LS2K1000=y diff --git a/bsp/ls2kdev/drivers/board.h b/bsp/ls2kdev/drivers/board.h index 6e2f85ec743083af793f7f61bf8f8272542b161a..aa2344ff764801f5a017e34e3fc29cf790af72ca 100644 --- a/bsp/ls2kdev/drivers/board.h +++ b/bsp/ls2kdev/drivers/board.h @@ -15,7 +15,7 @@ extern unsigned char __bss_end; -#define CPU_HZ (100 * 1000 * 1000) +#define CPU_HZ (1000 * 1000 * 1000) //QEMU 200*1000*1000 #define RT_HW_HEAP_BEGIN KSEG1BASE//(void*)&__bss_end #define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024) diff --git a/bsp/ls2kdev/rtconfig.h b/bsp/ls2kdev/rtconfig.h index aaeed71df54251a8f8601745e04d16c5f11621c9..a75d0ca0158f2a47e51346307aac4d8a68ea99d2 100644 --- a/bsp/ls2kdev/rtconfig.h +++ b/bsp/ls2kdev/rtconfig.h @@ -7,7 +7,7 @@ /* RT-Thread Kernel */ #define RT_NAME_MAX 8 -#define RT_ALIGN_SIZE 4 +#define RT_ALIGN_SIZE 8 #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 #define RT_TICK_PER_SECOND 100 diff --git a/bsp/nuclei/README.md b/bsp/nuclei/README.md new file mode 100644 index 0000000000000000000000000000000000000000..65e5dc655e93def0e04320c77a2debf2ddbf7b01 --- /dev/null +++ b/bsp/nuclei/README.md @@ -0,0 +1,16 @@ +# Nuclei RISC-V Processor Support Package + +This directory provided support for [Nuclei RISC-V Processor](https://nucleisys.com/) based board, currently +we mainly provided the following support package. + +| **BSP** | **Development Board Name** | +| :----------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | +| [gd32vf103_rvstar](gd32vf103_rvstar) | [Nuclei RV-STAR Arduino Compatible Development Board](https://www.riscv-mcu.com/quickstart-quickstart-index-u-RV_STAR.html) | + +**If you want to learn more about Nuclei Processors, please click the following links:** + +* [Professional RISC-V IPs](https://nucleisys.com/product.php) +* [Professional Nuclei Processor Development Boards](https://nucleisys.com/developboard.php) +* [Comprehensive Documents and Development Tools](https://nucleisys.com/download.php) +* [Active RISC-V IP and MCU Community](https://www.rvmcu.com/) +* [Professional University Program](https://nucleisys.com/campus.php) \ No newline at end of file diff --git a/bsp/nuclei/gd32vf103_rvstar/.config b/bsp/nuclei/gd32vf103_rvstar/.config index c68135acc47e95b502fc314c6b62583417613dcc..00a3354fde3650b7a6d07cb52ec16f2c978ee587 100644 --- a/bsp/nuclei/gd32vf103_rvstar/.config +++ b/bsp/nuclei/gd32vf103_rvstar/.config @@ -78,7 +78,7 @@ CONFIG_ARCH_RISCV32=y # CONFIG_RT_USING_COMPONENTS_INIT=y CONFIG_RT_USING_USER_MAIN=y -CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_STACK_SIZE=1024 CONFIG_RT_MAIN_THREAD_PRIORITY=10 # @@ -97,7 +97,7 @@ CONFIG_FINSH_USING_SYMTAB=y CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set CONFIG_FINSH_THREAD_PRIORITY=20 -CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_THREAD_STACK_SIZE=2048 CONFIG_FINSH_CMD_SIZE=80 # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_USING_MSH=y @@ -108,27 +108,18 @@ CONFIG_FINSH_ARG_MAX=10 # # Device virtual file system # -CONFIG_RT_USING_DFS=y -CONFIG_DFS_USING_WORKDIR=y -CONFIG_DFS_FILESYSTEMS_MAX=2 -CONFIG_DFS_FILESYSTEM_TYPES_MAX=2 -CONFIG_DFS_FD_MAX=16 -# CONFIG_RT_USING_DFS_MNTTABLE is not set -# CONFIG_RT_USING_DFS_ELMFAT is not set -CONFIG_RT_USING_DFS_DEVFS=y -# CONFIG_RT_USING_DFS_ROMFS is not set -# CONFIG_RT_USING_DFS_RAMFS is not set -# CONFIG_RT_USING_DFS_UFFS is not set -# CONFIG_RT_USING_DFS_JFFS2 is not set +# CONFIG_RT_USING_DFS is not set # # Device Drivers # CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_PIPE_BUFSZ=512 -# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +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_SERIAL_USING_DMA=y +# CONFIG_RT_SERIAL_USING_DMA is not set CONFIG_RT_SERIAL_RB_BUFSZ=64 # CONFIG_RT_USING_CAN is not set # CONFIG_RT_USING_HWTIMER is not set @@ -163,10 +154,6 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_LIBC=y # CONFIG_RT_USING_PTHREADS is not set -CONFIG_RT_USING_POSIX=y -# CONFIG_RT_USING_POSIX_MMAP is not set -# CONFIG_RT_USING_POSIX_TERMIOS is not set -# CONFIG_RT_USING_POSIX_AIO is not set # CONFIG_RT_USING_MODULE is not set # @@ -218,6 +205,7 @@ CONFIG_RT_USING_POSIX=y # 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_CJSON is not set # CONFIG_PKG_USING_JSMN is not set @@ -244,6 +232,7 @@ CONFIG_RT_USING_POSIX=y # 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 @@ -320,6 +309,7 @@ CONFIG_RT_USING_POSIX=y # 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_URLENCODE is not set # # system packages @@ -330,6 +320,7 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_LWEXT4 is not set # CONFIG_PKG_USING_PARTITION is not set # CONFIG_PKG_USING_FAL 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_LITTLEVGL2RTT is not set @@ -361,6 +352,7 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_LITTLED is not set # CONFIG_PKG_USING_LKDGUI is not set # CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set # CONFIG_PKG_USING_WM_LIBRARIES is not set # CONFIG_PKG_USING_KENDRYTE_SDK is not set # CONFIG_PKG_USING_INFRARED is not set @@ -386,10 +378,15 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_EASYBLINK is not set # CONFIG_PKG_USING_PMS_SERIES is not set CONFIG_PKG_USING_NUCLEI_SDK=y + +# +# !!!Nuclei SDK only works with Nuclei RISC-V Processor IP!!! +# CONFIG_PKG_NUCLEI_SDK_PATH="/packages/peripherals/nuclei_sdk" # CONFIG_PKG_USING_NUCLEI_SDK_V023 is not set CONFIG_PKG_USING_NUCLEI_SDK_LATEST_VERSION=y CONFIG_PKG_NUCLEI_SDK_VER="latest" +# CONFIG_PKG_USING_CAN_YMODEM is not set # # miscellaneous packages @@ -446,6 +443,13 @@ CONFIG_BSP_USING_UART=y # CONFIG_BSP_USING_UART2 is not set # CONFIG_BSP_USING_UART3 is not set CONFIG_BSP_USING_UART4=y +# CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_HWTIMER is not set +# CONFIG_BSP_USING_ADC is not set +# CONFIG_BSP_USING_WDT is not set +# CONFIG_BSP_USING_RTC is not set +# CONFIG_BSP_USING_PWM is not set # # Board extended module Drivers diff --git a/bsp/nuclei/gd32vf103_rvstar/README.md b/bsp/nuclei/gd32vf103_rvstar/README.md index f9575aa2eea321e7608b3ec025260c209edb8fe7..5b8c61804ac251736a2f9ae1b5ecf01a719cca42 100644 --- a/bsp/nuclei/gd32vf103_rvstar/README.md +++ b/bsp/nuclei/gd32vf103_rvstar/README.md @@ -2,17 +2,17 @@ ## 简介 -**RVSTAR开发板** 是由芯来科技公司推出的基于采用芯来科技RISC-V架构处理器芯片的GD32VF103的开发板。 +**RVSTAR开发板** 是由[芯来科技Nuclei](https://nucleisys.com/)公司推出的基于采用芯来科技RISC-V架构处理器芯片的GD32VF103的开发板。 更多关于 **RVSTAR开发板** 开发板的详细资料请参见 [RVSTAR开发板快速入门](https://www.rvmcu.com/quickstart-quickstart-index-u-RV_STAR.html) ### 板载资源 -| 硬件 | 描述 | -| --- | --- | -| 内核 | Nuclei N205 | +| 硬件 | 描述 | +| ---- | --------------- | +| 内核 | Nuclei N205 | | 架构 | 32-bit RV32IMAC | -| 主频 | 108 MHz | +| 主频 | 108 MHz | ## 工具安装 @@ -75,27 +75,28 @@ export PATH=~/Software/Nuclei/gcc/bin:~/Software/Nuclei/openocd/bin:$PATH 正常下载的输出如下: -~~~ +~~~bat +57856@DESKTOP-4LATIEU D:\workspace\Sourcecode\rt-thread\bsp\nuclei\gd32vf103_rvstar +> scons --run upload scons: Reading SConscript files ... Supported downloaded modes for board gd32vf103v_rvstar are flashxip, chosen downloaded mode is flashxip Upload application rtthread.elf using openocd and gdb riscv-nuclei-elf-gdb rtthread.elf -ex "set remotetimeout 240" -ex "target remote | openocd --pipe -f D:/workspace/Sourcecode/rt-thread/bsp/nuclei/gd32vf103_rvstar/packages/nuclei_sdk-latest/SoC/gd32vf103/Board/gd32vf103v_rvstar/openocd_gd32vf103.cfg" --batch -ex "monitor halt" -ex "monitor flash protect 0 0 last off" -ex "load" -ex "monitor resume" -ex "monitor shutdown" -ex "quit" D:\Software\Nuclei\gcc\bin\riscv-nuclei-elf-gdb.exe: warning: Couldn't determine a path for the index cache directory. - Nuclei OpenOCD, 64-bit Open On-Chip Debugger 0.10.0+dev-00014-g0eae03214 (2019-12-12-07:43) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html -rt_thread_idle_entry (parameter=0x0) at D:\workspace\Sourcecode\rt-thread\src\idle.c:251 -251 if (idle_hook_list[i] != RT_NULL) +rt_assert_handler (ex_string=ex_string@entry=0x800ab10 "0", func=func@entry=0x800ac14 <__FUNCTION__.3090> "rt_sem_take", line=line@entry=363) at D:\workspace\Sourcecode\rt-thread\src\kservice.c:1371 +1371 while (dummy == 0); cleared protection for sectors 0 through 127 on flash bank 0 Loading section .init, size 0x264 lma 0x8000000 -Loading section .text, size 0x140de lma 0x8000280 -Loading section .rodata, size 0x37c0 lma 0x8014360 -Loading section .data, size 0x404 lma 0x8017b20 -Start address 0x800015c, load size 98054 -Transfer rate: 8 KB/sec, 10894 bytes/write. +Loading section .text, size 0xa646 lma 0x8000280 +Loading section .rodata, size 0x2a80 lma 0x800a8c8 +Loading section .data, size 0x350 lma 0x800d348 +Start address 0x800015c, load size 54906 +Transfer rate: 6 KB/sec, 9151 bytes/write. shutdown command invoked A debugging session is active. @@ -112,38 +113,55 @@ initialize rti_board_start:0 done \ | / - RT - Thread Operating System - / | \ 4.0.3 build Apr 9 2020 + / | \ 4.0.3 build Jun 9 2020 2006 - 2020 Copyright by rt-thread team do components initialization. initialize rti_board_end:0 done -initialize dfs_init:0 done +initialize rt_work_sys_workqueue_init:0 done +initialize rt_hw_pin_init:0 done initialize libc_system_init:0 done initialize finsh_system_init:0 done -msh /> +msh > ``` 在串口终端(我这里使用的是TeraTerm)输入``ps``即可查看当前线程工作情况: ~~~ -msh />ps +msh >ps thread pri status sp stack size max used left tick error -------- --- ------- ---------- ---------- ------ ---------- --- -thread01 19 suspend 0x00000158 0x0000018c 87% 0x00000005 000 -thread00 19 suspend 0x00000158 0x0000018c 87% 0x00000005 000 -tshell 20 running 0x00000258 0x00001000 18% 0x00000004 000 -tidle0 31 ready 0x000000a8 0x0000018c 59% 0x0000000e 000 -timer 4 suspend 0x000000f8 0x00000200 49% 0x00000009 000 -main 10 suspend 0x00000168 0x00000800 36% 0x00000006 000 -msh /> +tshell 20 running 0x000000f8 0x00000800 21% 0x00000008 000 +sys_work 23 suspend 0x00000098 0x00000800 07% 0x0000000a 000 +tidle0 31 ready 0x000000b8 0x0000018c 46% 0x00000013 000 +timer 4 suspend 0x00000098 0x00000200 29% 0x00000009 000 +msh >list_device +device type ref count +-------- -------------------- ---------- +pin Miscellaneous Device 0 +uart4 Character Device 2 +msh >version + + \ | / +- RT - Thread Operating System + / | \ 4.0.3 build Jun 11 2020 + 2006 - 2020 Copyright by rt-thread team +msh >free +total memory: 14208 +used memory : 5248 +maximum allocated memory: 6424 ~~~ ### 调试程序 +#### 命令行GDB调试 + 在保证程序编译成功后, 在相同ENV终端执行``scons --run debug``进行代码在命令行下进行GDB调试。 正常的调试输出如下: -~~~ +~~~bat +57856@DESKTOP-4LATIEU D:\workspace\Sourcecode\rt-thread\bsp\nuclei\gd32vf103_rvstar +> scons --run debug scons: Reading SConscript files ... Supported downloaded modes for board gd32vf103v_rvstar are flashxip, chosen downloaded mode is flashxip Debug application rtthread.elf using openocd and gdb @@ -165,42 +183,112 @@ Find the GDB manual and other documentation resources online at: For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from rtthread.elf... -Remote debugging using | openocd --pipe -f D:/workspace/Sourcecode/rt-thread/bsp/nuclei/gd32vf103_rvstar/packages/nuclei_sdk-latest/SoC/gd32vf103/Board/gd32vf103v_rvstar/openocd_gd32vf103.cfg Nuclei OpenOCD, 64-bit Open On-Chip Debugger 0.10.0+dev-00014-g0eae03214 (2019-12-12-07:43) +Remote debugging using | openocd --pipe -f D:/workspace/Sourcecode/rt-thread/bsp/nuclei/gd32vf103_rvstar/packages/nuclei_sdk-latest/SoC/gd32vf103/Board/gd32vf103v_rvstar/openocd_gd32vf103.cfg +Nuclei OpenOCD, 64-bit Open On-Chip Debugger 0.10.0+dev-00014-g0eae03214 (2019-12-12-07:43) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html -rt_thread_idle_entry (parameter=0x0) at D:\workspace\Sourcecode\rt-thread\src\idle.c:249 -249 for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++) -(gdb) -(gdb) b main.c:35 -Breakpoint 1 at 0x8000290: file applications\main.c, line 35. +0x080011ca in rt_thread_idle_excute () at D:\workspace\Sourcecode\rt-thread\src\idle.c:153 +153 while (_has_defunct_thread()) +(gdb) b irq_entry +Breakpoint 1 at 0x8003840: file D:\workspace\Sourcecode\rt-thread\libcpu\risc-v\nuclei\interrupt_gcc.S, line 190. (gdb) c Continuing. Note: automatically using hardware breakpoints for read-only addresses. -Breakpoint 1, thread_entry (parameter=0x0) at applications\main.c:35 -35 rt_thread_mdelay(500); -(gdb) +Breakpoint 1, irq_entry () at D:\workspace\Sourcecode\rt-thread\libcpu\risc-v\nuclei\interrupt_gcc.S:190 +190 SAVE_CONTEXT +(gdb) c ~~~ 调试例子参见如下文档: * https://doc.nucleisys.com/nuclei_sdk/quickstart.html#debug-application -为了更方便的进行调试, 也可以下载**Nuclei Studio**集成开发环境, 创建一个Debug Configuration, 选择编译好的 -ELF文件, 然后配置OPENOCD和GDB即可, OPENOCD配置文件路径为**bsp\nuclei\gd32vf103_rvstar\packages\nuclei_sdk-latest\SoC\gd32vf103\Board\gd32vf103v_rvstar\openocd_gd32vf103.cfg** +#### Nuclei Studio IDE调试 + +为了更方便的进行图形化调试, 也可以下载并使用[**Nuclei Studio IDE**](https://nucleisys.com/download.php)集成开发环境. + +1. 打开Nuclei Studio IDE, 创建一个名为**Nuclei_RT-Thread**的**C Project**,Project Type选择**Empty Project**, + Toolchain选择**RISC-V Cross GCC**, 然后点击**Finish**. + + ![Create A RISC-V C Project](doc/images/create_c_project.png) + +2. 选中**rt-thread**的代码目录,然后鼠标左键拖到Nuclei Studio中创建好的**Nuclei_RT-Thread**工程中,选择 + **Link to files and folders**, 点击**OK**, 就将**rt-thread**的代码拖到了工程中并创建软链接,注意这里建立的工程 + 仅用于调试,不可以用于编译,编译请使用上文中提到的`scons`命令。 + + ![Drop and link RT-Thread source code](doc/images/link_rtthread_code.png) + +3. 创建一个OpenOCD Debugging Configuration, 选择编译好的ELF文件, 并选定**Disable auto build**, 如下图所示: + + ![Create OpenOCD Debugging Configuration](doc/images/create_gdb_cfg.png) +4. 然后打开**Debugger**Tab, 配置好OPENOCD的配置文件路径, 其中OPENOCD配置文件路径为 +*bsp\nuclei\gd32vf103_rvstar\packages\nuclei_sdk-latest\SoC\gd32vf103\Board\gd32vf103v_rvstar\openocd_gd32vf103.cfg*, + 请在配置时使用完整绝对路径,根据自己文件所在目录来提供。配置完毕后,点击 **Debug**,开始下载调试。 + + ![Configure OpenOCD configuration file](doc/images/config_openocd_cfg.png) + +5. 最终调试界面如下所示 + + ![Debug in Nuclei Studio IDE](doc/images/start_debug_in_ide.png) + +6. 上面步骤中的路径请根据自己的环境进行调整,调试时请确保开发板正常连接到电脑,并且调试器驱动安装正确。 ## 驱动支持情况 -| 驱动 | 支持情况 | 备注 | -| ------ | ---- | :------: | -| UART | 支持 | RV-STAR板载串口是UART4 | +| 驱动 | 支持情况 | 备注 | +| ------- | -------- | :------------------------------: | +| UART | 支持 | RV-STAR板载串口是UART4, 默认使能 | +| GPIO | 支持 | 默认使能,支持中断控制 | +| SPI | 支持 | 默认关闭 | +| I2C | 支持 | 默认关闭 | +| HWTIMER | 支持 | 默认关闭 | +| PWM | 支持 | 默认关闭 | +| WDT | 支持 | 默认关闭 | +| RTC | 支持 | 默认关闭 | +| ADC | 支持 | 默认关闭 | + +### 适配开发板Pinmux + +如果需要使用到其他的外设驱动,则首先需要运行`menuconfig`命令,在 +`Hardware Drivers Config -> On-chip Peripheral Drivers`中使能对应的外设接口, +但是由于针对不同的外设接口GPIO的pinux配置不一样,开发者仍需要根据自己的需求 +在 `board/board.c` 中的 `rt_hw_drivers_init`入口函数中找到需要使用到的子函数, +并在对应的子函数中进行功能适配。 + +**使用举例** + +* I2C外设Pinmux + +如果需要将I2C1的SCL和SDA配置在PB10和PB11,首先需要在menuconfig中将I2C1使能,然后 +更改board.c中`rt_hw_i2c_drvinit`函数,并进行如下设定。 + +~~~c +/* Configure PB10 PB11 (I2C1 SCL SDA) as alternate function */ +gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11); +~~~ + +* SPI外设Pinmux + +如果需要将SPI0的SCK MISO和MOSI配置在PA5, PA6和PA7,首先需要在menuconfig中将SPI0使能, +然后更改board.c中的`rt_hw_spi_drvinit`函数,并进行如下设定。 + +~~~c +/* Configure PA5 PA6 PA7 (SPI0 SCK MISO MOSI) as alternate function */ +gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7); +gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6); +~~~ + +* 其余类似的外设也是如上做适配处理 -**注:** +### 注意 - 适配RT-Thread的驱动框架的代码在 [../libraries/gd32vf103/HAL_Drivers](../libraries/gd32vf103/HAL_Drivers)目录下。 - 如果有开发者想适配更多的驱动, 请在对应目录下增加驱动适配支持。 +- GD32VF103的驱动适配开关在 `menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers` 可以找到。 +- HWTIMER和PWM都是采用的TIMER模块进行功能实现,所以在使用驱动时,请务必注意不要重叠使用相同模块。 ## 联系人信息 diff --git a/bsp/nuclei/gd32vf103_rvstar/SConstruct b/bsp/nuclei/gd32vf103_rvstar/SConstruct index 7adcd690708c7d496bb977ed4d2b89a3f922cdb3..58c5d745d7a2085f8d46d95f69b2c5ebd4fe70e8 100644 --- a/bsp/nuclei/gd32vf103_rvstar/SConstruct +++ b/bsp/nuclei/gd32vf103_rvstar/SConstruct @@ -24,7 +24,8 @@ DefaultEnvironment(tools=[]) env = Environment(tools = ['mingw'], AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, - AR = rtconfig.AR, ARFLAGS = '-rc', + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', LIBS = rtconfig.LIBS, LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH) env['ASCOM'] = env['ASPPCOM'] @@ -50,7 +51,11 @@ objs = PrepareBuilding(env, RTT_ROOT) bsp_library_type = rtconfig.NUCLEI_SDK_SOC rtconfig.BSP_LIBRARY_TYPE = bsp_library_type -openocd_cfg = rtconfig.NUCLEI_SDK_OPENOCD_CFG.replace('\\', '/') +if hasattr(rtconfig, 'NUCLEI_SDK_OPENOCD_CFG'): + openocd_cfg = rtconfig.NUCLEI_SDK_OPENOCD_CFG.replace('\\', '/') +else: + print("ERROR: Nuclei SDK package is not yet downloaded, please execute in command line first!") + exit(0) # include hal drivers hal_sconscript = os.path.join(libraries_path_prefix, bsp_library_type, 'HAL_Drivers', 'SConscript') diff --git a/bsp/nuclei/gd32vf103_rvstar/board/Kconfig b/bsp/nuclei/gd32vf103_rvstar/board/Kconfig index 5165ac7629afe649671874440e5d973a85c655a2..efb38aeaf73c844dcbb71c9737564dc80ba396ae 100644 --- a/bsp/nuclei/gd32vf103_rvstar/board/Kconfig +++ b/bsp/nuclei/gd32vf103_rvstar/board/Kconfig @@ -38,6 +38,108 @@ menu "On-chip Peripheral Drivers" default n endif + menuconfig BSP_USING_I2C + bool "Enable I2C" + default n + select RT_USING_I2C + if BSP_USING_I2C + config BSP_USING_I2C0 + bool "Enable I2C0" + default n + config BSP_USING_I2C1 + bool "Enable I2C1" + default n + endif + + menuconfig BSP_USING_SPI + bool "Enable SPI" + default n + select RT_USING_SPI + if BSP_USING_SPI + config BSP_USING_SPI0 + bool "Enable SPI0" + default n + config BSP_USING_SPI1 + bool "Enable SPI1" + default n + config BSP_USING_SPI2 + bool "Enable SPI2" + default n + endif + + menuconfig BSP_USING_HWTIMER + bool "Enable TIMER" + default n + select RT_USING_HWTIMER + if BSP_USING_HWTIMER + config BSP_USING_HWTIMER0 + bool "Enable TIMER0" + default n + config BSP_USING_HWTIMER1 + bool "Enable TIMER1" + default n + config BSP_USING_HWTIMER2 + bool "Enable TIMER2" + default n + config BSP_USING_HWTIMER3 + bool "Enable TIMER3" + default n + config BSP_USING_HWTIMER4 + bool "Enable TIMER4" + default n + config BSP_USING_HWTIMER5 + bool "Enable TIMER5" + default n + config BSP_USING_HWTIMER6 + bool "Enable TIMER6" + default n + endif + + menuconfig BSP_USING_ADC + bool "Enable ADC" + default n + select RT_USING_ADC + if BSP_USING_ADC + config BSP_USING_ADC0 + bool "Enable ADC0" + default n + config BSP_USING_ADC1 + bool "Enable ADC1" + default n + endif + + menuconfig BSP_USING_WDT + bool "Enable WDT" + default n + select RT_USING_WDT + + menuconfig BSP_USING_RTC + bool "Enable RTC" + default n + select RT_USING_RTC + + menuconfig BSP_USING_PWM + bool "Enable PWM" + default n + select RT_USING_PWM + if BSP_USING_PWM + config BSP_USING_PWM0 + bool "Enable PWM0" + default n + config BSP_USING_PWM1 + bool "Enable PWM1" + default n + config BSP_USING_PWM2 + bool "Enable PWM2" + default n + config BSP_USING_PWM3 + bool "Enable PWM3" + default n + config BSP_USING_PWM4 + bool "Enable PWM4" + default n + endif + endmenu menu "Board extended module Drivers" diff --git a/bsp/nuclei/gd32vf103_rvstar/board/board.c b/bsp/nuclei/gd32vf103_rvstar/board/board.c index 7dad8750069113d3bbf74eba2cfba91da10cc9f0..1a470f9b1e72a17482f26f724fef987d07b78949 100644 --- a/bsp/nuclei/gd32vf103_rvstar/board/board.c +++ b/bsp/nuclei/gd32vf103_rvstar/board/board.c @@ -32,6 +32,96 @@ extern void *_heap_end; */ extern void _init(void); +/* + * - Check MCU pin assignment here https://doc.nucleisys.com/nuclei_board_labs/hw/hw.html + * - If you changed menuconfig to use different peripherals such as SPI, ADC, GPIO, + * HWTIMER, I2C, PWM, UART, WDT, RTC, please add or change related pinmux configuration + * code in functions(rt_hw_*_drvinit) below + */ + +void rt_hw_spi_drvinit(void) +{ + +} + +void rt_hw_adc_drvinit(void) +{ + +} + +void rt_hw_gpio_drvinit(void) +{ + // Clock on all the GPIOs and AF + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_GPIOD); + rcu_periph_clock_enable(RCU_GPIOE); + rcu_periph_clock_enable(RCU_AF); +} + +void rt_hw_hwtimer_drvinit(void) +{ + +} + +void rt_hw_i2c_drvinit(void) +{ + +} + +void rt_hw_pwm_drvinit(void) +{ + +} + +void rt_hw_rtc_drvinit(void) +{ + +} + +void rt_hw_uart_drvinit(void) +{ + /* Notice: Debug UART4 GPIO pins are already initialized in nuclei_sdk */ + +} + +void rt_hw_wdt_drvinit(void) +{ + +} + +void rt_hw_drivers_init(void) +{ +#ifdef RT_USING_PIN + rt_hw_gpio_drvinit(); +#endif +#ifdef BSP_USING_UART + rt_hw_uart_drvinit(); +#endif +#ifdef BSP_USING_SPI + rt_hw_spi_drvinit(); +#endif +#ifdef BSP_USING_I2C + rt_hw_i2c_drvinit(); +#endif +#ifdef BSP_USING_ADC + rt_hw_adc_drvinit(); +#endif +#ifdef BSP_USING_WDT + rt_hw_wdt_drvinit(); +#endif +#ifdef BSP_USING_RTC + rt_hw_rtc_drvinit(); +#endif +#ifdef BSP_USING_HWTIMER + rt_hw_hwtimer_drvinit(); +#endif +#ifdef BSP_USING_PWM + rt_hw_pwm_drvinit(); +#endif +} + /** * @brief Setup hardware board for rt-thread * @@ -47,6 +137,9 @@ void rt_hw_board_init(void) _init(); // __libc_init_array is not used in RT-Thread + /* Board hardware drivers initialization */ + rt_hw_drivers_init(); + /* USART driver initialization is open by default */ #ifdef RT_USING_SERIAL rt_hw_usart_init(); @@ -61,6 +154,7 @@ void rt_hw_board_init(void) #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif + } /******************** end of file *******************/ diff --git a/bsp/nuclei/gd32vf103_rvstar/doc/images/config_openocd_cfg.png b/bsp/nuclei/gd32vf103_rvstar/doc/images/config_openocd_cfg.png new file mode 100644 index 0000000000000000000000000000000000000000..887c8402e2f4d50d56ed505714425e4cb9cf950f Binary files /dev/null and b/bsp/nuclei/gd32vf103_rvstar/doc/images/config_openocd_cfg.png differ diff --git a/bsp/nuclei/gd32vf103_rvstar/doc/images/create_c_project.png b/bsp/nuclei/gd32vf103_rvstar/doc/images/create_c_project.png new file mode 100644 index 0000000000000000000000000000000000000000..28537c2630a9c915d72d4b81543adcbc4c75a7b1 Binary files /dev/null and b/bsp/nuclei/gd32vf103_rvstar/doc/images/create_c_project.png differ diff --git a/bsp/nuclei/gd32vf103_rvstar/doc/images/create_gdb_cfg.png b/bsp/nuclei/gd32vf103_rvstar/doc/images/create_gdb_cfg.png new file mode 100644 index 0000000000000000000000000000000000000000..f6642ef8446d0a9dd76505c20fc3aafc918439b5 Binary files /dev/null and b/bsp/nuclei/gd32vf103_rvstar/doc/images/create_gdb_cfg.png differ diff --git a/bsp/nuclei/gd32vf103_rvstar/doc/images/link_rtthread_code.png b/bsp/nuclei/gd32vf103_rvstar/doc/images/link_rtthread_code.png new file mode 100644 index 0000000000000000000000000000000000000000..69b7bd351984555f57d2680aa4bf877ea4357ef9 Binary files /dev/null and b/bsp/nuclei/gd32vf103_rvstar/doc/images/link_rtthread_code.png differ diff --git a/bsp/nuclei/gd32vf103_rvstar/doc/images/start_debug_in_ide.png b/bsp/nuclei/gd32vf103_rvstar/doc/images/start_debug_in_ide.png new file mode 100644 index 0000000000000000000000000000000000000000..153b1350154dd4a560bcfa2422ce366748342d22 Binary files /dev/null and b/bsp/nuclei/gd32vf103_rvstar/doc/images/start_debug_in_ide.png differ diff --git a/bsp/nuclei/gd32vf103_rvstar/rtconfig.h b/bsp/nuclei/gd32vf103_rvstar/rtconfig.h index 2498e39e9db4af3dd2bff3ef1430002cef2a7c2c..88c805300576a54ea64ce1096696fd266a901feb 100644 --- a/bsp/nuclei/gd32vf103_rvstar/rtconfig.h +++ b/bsp/nuclei/gd32vf103_rvstar/rtconfig.h @@ -52,7 +52,7 @@ #define RT_USING_COMPONENTS_INIT #define RT_USING_USER_MAIN -#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_STACK_SIZE 1024 #define RT_MAIN_THREAD_PRIORITY 10 /* C++ features */ @@ -67,7 +67,7 @@ #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION #define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_THREAD_STACK_SIZE 2048 #define FINSH_CMD_SIZE 80 #define FINSH_USING_MSH #define FINSH_USING_MSH_DEFAULT @@ -75,19 +75,15 @@ /* Device virtual file system */ -#define RT_USING_DFS -#define DFS_USING_WORKDIR -#define DFS_FILESYSTEMS_MAX 2 -#define DFS_FILESYSTEM_TYPES_MAX 2 -#define DFS_FD_MAX 16 -#define RT_USING_DFS_DEVFS /* Device Drivers */ #define RT_USING_DEVICE_IPC #define RT_PIPE_BUFSZ 512 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 #define RT_USING_SERIAL -#define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_PIN @@ -97,7 +93,6 @@ /* POSIX layer and C standard library */ #define RT_USING_LIBC -#define RT_USING_POSIX /* Network */ @@ -153,6 +148,9 @@ /* peripheral libraries and drivers */ #define PKG_USING_NUCLEI_SDK + +/* !!!Nuclei SDK only works with Nuclei RISC-V Processor IP!!! */ + #define PKG_USING_NUCLEI_SDK_LATEST_VERSION /* miscellaneous packages */ diff --git a/bsp/nuclei/gd32vf103_rvstar/rtconfig.py b/bsp/nuclei/gd32vf103_rvstar/rtconfig.py index bf74338e8a5b5fc75f488ef78436210cb6daaf85..4ea3c42133e63bb48254dd91ea89b6ff464fe01a 100644 --- a/bsp/nuclei/gd32vf103_rvstar/rtconfig.py +++ b/bsp/nuclei/gd32vf103_rvstar/rtconfig.py @@ -23,7 +23,6 @@ else: BUILD = 'debug' # Fixed configurations below -NUCLEI_SDK_OPENOCD_CFG = "type in your config" NUCLEI_SDK_SOC = "gd32vf103" NUCLEI_SDK_BOARD = "gd32vf103v_rvstar" NUCLEI_SDK_DOWNLOAD = "flashxip" @@ -46,13 +45,14 @@ if PLATFORM == 'gcc': CFLAGS = ' -ffunction-sections -fdata-sections -fno-common ' AFLAGS = CFLAGS LFLAGS = ' --specs=nano.specs --specs=nosys.specs -nostartfiles -Wl,--gc-sections ' - LFLAGS += ' -Wl,-cref,-Map=rtthread.map' + LFLAGS += ' -Wl,-cref,-Map=rtthread.map ' LFLAGS += ' -u _isatty -u _write -u _sbrk -u _read -u _close -u _fstat -u _lseek ' CPATH = '' LPATH = '' + LIBS = ['stdc++'] if BUILD == 'debug': - CFLAGS += ' -O0 -ggdb' + CFLAGS += ' -O2 -Os -ggdb' AFLAGS += ' -ggdb' else: CFLAGS += ' -O2 -Os' @@ -62,9 +62,9 @@ if PLATFORM == 'gcc': DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' -def dist_handle(BSP_ROOT): +def dist_handle(BSP_ROOT, dist_dir): import sys cwd_path = os.getcwd() sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) from sdk_dist import dist_do_building - dist_do_building(BSP_ROOT) + dist_do_building(BSP_ROOT, dist_dir) diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/SConscript b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/SConscript index 4761127102949a9bafd4f3978efed45c524e6cbf..b9cdd5b795a89aa01d3b9920991ee2b1df6424a6 100644 --- a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/SConscript +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/SConscript @@ -14,6 +14,28 @@ if GetDepend(['RT_USING_PIN']): if GetDepend(['RT_USING_SERIAL']): src += ['drv_usart.c'] +if GetDepend(['RT_USING_I2C']): + src += ['drv_i2c.c'] + +if GetDepend(['RT_USING_SPI']): + src += ['drv_spi.c'] + +if GetDepend(['RT_USING_HWTIMER']): + src += ['drv_hwtimer.c'] + +if GetDepend(['RT_USING_ADC']): + src += ['drv_adc.c'] + +if GetDepend(['RT_USING_WDT']): + src += ['drv_wdt.c'] + +if GetDepend(['RT_USING_RTC']): + src += ['drv_rtc.c'] + +if GetDepend(['RT_USING_PWM']): + src += ['drv_pwm.c'] + + path = [cwd] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path) diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_adc.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..5e463be51d744a825bb616c6016c2368560b8132 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_adc.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-03 hqfang the first version. + * + */ +#include "drv_adc.h" + +#ifdef BSP_USING_ADC + +#if !defined(BSP_USING_ADC0) && !defined(BSP_USING_ADC1) + #error "Please define at least one BSP_USING_ADCx" + /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable ADC */ +#endif + + +static struct gd32_adc_config adc_config[] = +{ +#ifdef BSP_USING_ADC0 + { + "adc0", + ADC0, + }, +#endif +#ifdef BSP_USING_ADC1 + { + "adc1", + ADC1, + }, +#endif +}; + +static struct gd32_adc adc_obj[sizeof(adc_config) / sizeof(adc_config[0])] = {0}; + +static void gd32_adc_init(struct gd32_adc_config *config) +{ + RT_ASSERT(config != RT_NULL); + adc_deinit(config->adc_periph); + + ADC_CTL0(config->adc_periph) &= ~(ADC_CTL0_SYNCM); + ADC_CTL0(config->adc_periph) |= ADC_MODE_FREE; + + ADC_CTL1(config->adc_periph) |= ADC_CTL1_TSVREN; + + adc_resolution_config(config->adc_periph, ADC_RESOLUTION_12B); + /* ADC contineous function enable */ + adc_special_function_config(config->adc_periph, ADC_SCAN_MODE, ENABLE); + /* ADC data alignment config */ + adc_data_alignment_config(config->adc_periph, ADC_DATAALIGN_RIGHT); + /* ADC channel length config */ + adc_channel_length_config(config->adc_periph, ADC_REGULAR_CHANNEL, 1); + adc_external_trigger_source_config(config->adc_periph, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE); + + /* ADC enable */ + adc_external_trigger_config(config->adc_periph, ADC_REGULAR_CHANNEL, ENABLE); + adc_enable(config->adc_periph); + + adc_calibration_enable(config->adc_periph); +} + +static rt_err_t gd32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled) +{ + if (channel > ADC_CHANNEL_17) + { + return RT_EINVAL; + } + return RT_EOK; +} + +static rt_err_t gd32_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value) +{ + struct gd32_adc_config *config; + RT_ASSERT(device != RT_NULL); + + if (channel > ADC_CHANNEL_17) + { + return RT_EINVAL; + } + config = (struct gd32_adc_config *)(device->parent.user_data); + + if (channel > ADC_CHANNEL_15) + { + adc_regular_channel_config(config->adc_periph, 0, channel, ADC_SAMPLETIME_239POINT5); + } + else + { + adc_regular_channel_config(config->adc_periph, 0, channel, ADC_SAMPLETIME_55POINT5); + } + adc_software_trigger_enable(config->adc_periph, ADC_REGULAR_CHANNEL); + + while (SET != adc_flag_get(config->adc_periph, ADC_FLAG_EOC)); + adc_flag_clear(config->adc_periph, ADC_FLAG_EOC); + + *value = ADC_RDATA(config->adc_periph); + + return RT_EOK; +} + +static struct rt_adc_ops gd32_adc_ops = +{ + .enabled = gd32_adc_enabled, + .convert = gd32_adc_convert, +}; + +int rt_hw_adc_init(void) +{ + int i = 0; + int result = RT_EOK; + +#if defined(BSP_USING_ADC0) + rcu_periph_clock_enable(RCU_ADC0); +#endif +#if defined(BSP_USING_ADC1) + rcu_periph_clock_enable(RCU_ADC1); +#endif + + rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8); + + for (i = 0; i < sizeof(adc_obj) / sizeof(adc_obj[0]); i++) + { + adc_obj[i].config = &adc_config[i]; + gd32_adc_init(&adc_config[i]); + rt_hw_adc_register(&adc_obj[i].adc_device, \ + adc_obj[i].config->name, &gd32_adc_ops, adc_obj[i].config); + } + + return result; +} + +INIT_DEVICE_EXPORT(rt_hw_adc_init); + +#endif /* BSP_USING_ADC */ + diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_adc.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..a3c7380bb020a36e82b6afde7e2baf79006280b0 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_adc.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-03 hqfang first implementation. + */ + +#ifndef __DRV_ADC__ +#define __DRV_ADC__ + +#include +#include +#include +#include + +/* gd32 config class */ +struct gd32_adc_config +{ + const char *name; + rt_uint32_t adc_periph; +}; + +struct gd32_adc +{ + struct rt_adc_device adc_device; + struct gd32_adc_config *config; +}; + +#endif diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.c index 75ab81f18e918ec359927d40dcd1e097c329a897..f7572a57dbdc6c0399a0474200552492f5dd9e1e 100644 --- a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.c +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.c @@ -337,8 +337,11 @@ static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, const struct pin_irq_map *irqmap; rt_base_t level; rt_int32_t irqindex = -1; + rt_uint8_t portsrc = 0, pinsrc = 0; exti_trig_type_enum trigger_mode; + portsrc = pin >> 4; + pinsrc = pin % 16; index = get_pin(pin); if (index == RT_NULL) { @@ -378,8 +381,9 @@ static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_hw_interrupt_enable(level); return RT_EINVAL; } + /* connect EXTI line to GPIO pin */ - gpio_exti_source_select(index->gpio, index->pin); + gpio_exti_source_select(portsrc, pinsrc); /* configure EXTI line */ exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode); @@ -391,6 +395,8 @@ static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, ECLIC_EnableIRQ(irqmap->irqno); pin_irq_enable_mask |= irqmap->pinbit; + exti_interrupt_enable((exti_line_enum)(index->pin)); + rt_hw_interrupt_enable(level); } else if (enabled == PIN_IRQ_DISABLE) @@ -405,6 +411,7 @@ static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, if (!(pin_irq_enable_mask & (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9))) { ECLIC_DisableIRQ(irqmap->irqno); + exti_interrupt_disable((exti_line_enum)(index->pin)); } } else if ((irqmap->pinbit >= GPIO_PIN_10) && (irqmap->pinbit <= GPIO_PIN_15)) @@ -412,11 +419,13 @@ static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, if (!(pin_irq_enable_mask & (GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15))) { ECLIC_DisableIRQ(irqmap->irqno); + exti_interrupt_disable((exti_line_enum)(index->pin)); } } else { ECLIC_DisableIRQ(irqmap->irqno); + exti_interrupt_disable((exti_line_enum)(index->pin)); } } else @@ -515,6 +524,7 @@ int rt_hw_pin_init(void) rcu_periph_clock_enable(RCU_AF); return rt_device_pin_register("pin", &_gd32_pin_ops, RT_NULL); } -INIT_BOARD_EXPORT(rt_hw_pin_init); + +INIT_DEVICE_EXPORT(rt_hw_pin_init); #endif /* RT_USING_PIN */ diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_hwtimer.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_hwtimer.c new file mode 100644 index 0000000000000000000000000000000000000000..dd351ee146667d06aeb152d408a4d85d960ab6bd --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_hwtimer.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-05-12 hqfang first version + */ + +#include "drv_hwtimer.h" + +#ifdef BSP_USING_HWTIMER + +#if !defined(BSP_USING_HWTIMER0) && !defined(BSP_USING_HWTIMER1) && !defined(BSP_USING_HWTIMER2) \ + && !defined(BSP_USING_HWTIMER3) && !defined(BSP_USING_HWTIMER4) + #error "Please define at least one BSP_USING_HWTIMERx" + /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable HWTIMER */ +#endif + +static struct gd32_hwtimer_config hwtimer_config[] = +{ +#ifdef BSP_USING_HWTIMER0 + { + "timer0", + TIMER0, + TIMER0_UP_IRQn, + }, +#endif +#ifdef BSP_USING_HWTIMER1 + { + "timer1", + TIMER1, + TIMER1_IRQn, + }, +#endif +#ifdef BSP_USING_HWTIMER2 + { + "timer2", + TIMER2, + TIMER2_IRQn, + }, +#endif +#ifdef BSP_USING_HWTIMER3 + { + "timer3", + TIMER3, + TIMER3_IRQn, + }, +#endif +#ifdef BSP_USING_HWTIMER4 + { + "timer4", + TIMER4, + TIMER4_IRQn, + }, +#endif +#ifdef BSP_USING_HWTIMER5 + { + "timer5", + TIMER5, + TIMER5_IRQn, + }, +#endif +#ifdef BSP_USING_HWTIMER6 + { + "timer6", + TIMER6, + TIMER6_IRQn, + }, +#endif +}; + +static struct gd32_hwtimer hwtimer_obj[sizeof(hwtimer_config) / sizeof(hwtimer_config[0])] = {0}; + +static rt_err_t gd32_hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args) +{ + rt_err_t err = RT_EOK; + struct gd32_hwtimer_config *config; + RT_ASSERT(timer != RT_NULL); + + config = (struct gd32_hwtimer_config *)timer->parent.user_data; + + switch (cmd) + { + case HWTIMER_CTRL_FREQ_SET: + { + uint32_t clk; + uint8_t clkpre; + uint32_t pre; + if (config->timer_periph != TIMER0) + { + clk = rcu_clock_freq_get(CK_APB1); + clkpre = GET_BITS(RCU_CFG0, 8, 10); + } + else + { + clk = rcu_clock_freq_get(CK_APB2); + clkpre = GET_BITS(RCU_CFG0, 11, 13); + } + if (clkpre >= 4) + { + clk = clk * 2; + } + pre = (clk / * ((uint32_t *)args)) - 1; + TIMER_PSC(config->timer_periph) = (uint32_t)pre; + } + break; + case HWTIMER_CTRL_STOP: + timer_disable(config->timer_periph); + break; + default: + err = -RT_ENOSYS; + break; + } + return err; +} + +static rt_uint32_t gd32_hwtimer_count_get(rt_hwtimer_t *timer) +{ + rt_uint32_t CurrentTimer_Count; + struct gd32_hwtimer_config *config; + RT_ASSERT(timer != RT_NULL); + + config = (struct gd32_hwtimer_config *)timer->parent.user_data; + + CurrentTimer_Count = timer_counter_read(config->timer_periph); + + return CurrentTimer_Count; +} + +static void gd32_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state) +{ + struct gd32_hwtimer_config *config; + timer_parameter_struct initpara; + RT_ASSERT(timer != RT_NULL); + config = (struct gd32_hwtimer_config *)timer->parent.user_data; + + if (state == 1) + { + timer_deinit(config->timer_periph); + timer_struct_para_init(&initpara); + timer_init(config->timer_periph, &initpara); + } + else + { + timer_disable(config->timer_periph); + timer_interrupt_enable(config->timer_periph, TIMER_INT_FLAG_UP); + ECLIC_DisableIRQ(config->irqn); + } +} + +static rt_err_t gd32_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode) +{ + struct gd32_hwtimer_config *config; + RT_ASSERT(timer != RT_NULL); + config = (struct gd32_hwtimer_config *)timer->parent.user_data; + + if (mode == HWTIMER_MODE_ONESHOT) + { + timer_single_pulse_mode_config(config->timer_periph, TIMER_SP_MODE_SINGLE); + } + else + { + timer_single_pulse_mode_config(config->timer_periph, TIMER_SP_MODE_REPETITIVE); + } + timer_counter_value_config(config->timer_periph, 0); + timer_autoreload_value_config(config->timer_periph, cnt); + timer_interrupt_enable(config->timer_periph, TIMER_INT_FLAG_UP); + timer_enable(config->timer_periph); + ECLIC_EnableIRQ(config->irqn); + + return RT_EOK; +} + +static void gd32_hwtimer_stop(rt_hwtimer_t *timer) +{ + struct gd32_hwtimer_config *config; + RT_ASSERT(timer != RT_NULL); + config = (struct gd32_hwtimer_config *)timer->parent.user_data; + + timer_disable(config->timer_periph); + + ECLIC_DisableIRQ(config->irqn); +} + +static const struct rt_hwtimer_ops gd32_hwtimer_ops = +{ + .init = gd32_hwtimer_init, + .start = gd32_hwtimer_start, + .stop = gd32_hwtimer_stop, + .count_get = gd32_hwtimer_count_get, + .control = gd32_hwtimer_control, +}; + +static const struct rt_hwtimer_info gd32_hwtimer_info = +{ + 54000000, /* the maximum count frequency can be set */ + 1000, /* the minimum count frequency can be set */ + 0xFFFF, + HWTIMER_CNTMODE_UP, +}; + +#ifdef BSP_USING_HWTIMER0 + +void TIMER0_UP_IRQHandler(void) +{ + timer_interrupt_flag_clear(hwtimer_obj[0].config->timer_periph, TIMER_INT_FLAG_UP); + rt_device_hwtimer_isr(&hwtimer_obj[0].time_device); +} + +#endif + +#ifdef BSP_USING_HWTIMER1 + +void TIMER1_IRQHandler(void) +{ + timer_interrupt_flag_clear(hwtimer_obj[1].config->timer_periph, TIMER_INT_FLAG_UP); + rt_device_hwtimer_isr(&hwtimer_obj[1].time_device); +} + +#endif + +#ifdef BSP_USING_HWTIMER2 + +void TIMER2_IRQHandler(void) +{ + timer_interrupt_flag_clear(hwtimer_obj[2].config->timer_periph, TIMER_INT_FLAG_UP); + rt_device_hwtimer_isr(&hwtimer_obj[2].time_device); +} + +#endif + +#ifdef BSP_USING_HWTIMER3 + +void TIMER3_IRQHandler(void) +{ + timer_interrupt_flag_clear(hwtimer_obj[3].config->timer_periph, TIMER_INT_FLAG_UP); + rt_device_hwtimer_isr(&hwtimer_obj[3].time_device); +} + +#endif + +#ifdef BSP_USING_HWTIMER4 + +void TIMER4_IRQHandler(void) +{ + timer_interrupt_flag_clear(hwtimer_obj[4].config->timer_periph, TIMER_INT_FLAG_UP); + rt_device_hwtimer_isr(&hwtimer_obj[4].time_device); +} + +#endif + +#ifdef BSP_USING_HWTIMER5 + +void TIMER5_IRQHandler(void) +{ + timer_interrupt_flag_clear(hwtimer_obj[5].config->timer_periph, TIMER_INT_FLAG_UP); + rt_device_hwtimer_isr(&hwtimer_obj[5].time_device); +} + +#endif + +#ifdef BSP_USING_HWTIMER6 + +void TIMER6_IRQHandler(void) +{ + timer_interrupt_flag_clear(hwtimer_obj[6].config->timer_periph, TIMER_INT_FLAG_UP); + rt_device_hwtimer_isr(&hwtimer_obj[6].time_device); +} + +#endif + +static int rt_hwtimer_init(void) +{ + int i = 0; + int result = RT_EOK; + +#ifdef BSP_USING_HWTIMER0 + rcu_periph_clock_enable(RCU_TIMER0); +#endif +#ifdef BSP_USING_HWTIMER1 + rcu_periph_clock_enable(RCU_TIMER1); +#endif +#ifdef BSP_USING_HWTIMER2 + rcu_periph_clock_enable(RCU_TIMER2); +#endif +#ifdef BSP_USING_HWTIMER3 + rcu_periph_clock_enable(RCU_TIMER3); +#endif +#ifdef BSP_USING_HWTIMER4 + rcu_periph_clock_enable(RCU_TIMER4); +#endif +#ifdef BSP_USING_HWTIMER5 + rcu_periph_clock_enable(RCU_TIMER5); +#endif +#ifdef BSP_USING_HWTIMER6 + rcu_periph_clock_enable(RCU_TIMER6); +#endif + + for (i = 0; i < sizeof(hwtimer_obj) / sizeof(hwtimer_obj[0]); i++) + { + hwtimer_obj[i].time_device.info = &gd32_hwtimer_info; + hwtimer_obj[i].time_device.ops = &gd32_hwtimer_ops; + hwtimer_obj[i].config = &hwtimer_config[i]; + rt_device_hwtimer_register(&hwtimer_obj[i].time_device, \ + hwtimer_obj[i].config->name, hwtimer_obj[i].config); + } + + return result; +} + +INIT_DEVICE_EXPORT(rt_hwtimer_init); + +#endif /* RT_USING_HWTIMER */ diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_hwtimer.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_hwtimer.h new file mode 100644 index 0000000000000000000000000000000000000000..f4664c9d38458900ae8a3f4680c110f82d6a1b9b --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_hwtimer.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2029-05-06 hqfang first implementation. + */ + +#ifndef __DRV_HWTIMER__ +#define __DRV_HWTIMER__ + +#include +#include +#include +#include + +/* gd32 config class */ +struct gd32_hwtimer_config +{ + const char *name; + rt_uint32_t timer_periph; + IRQn_Type irqn; +}; + +struct gd32_hwtimer +{ + rt_hwtimer_t time_device; + struct gd32_hwtimer_config *config; +}; + +#endif diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_i2c.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..94aa0e234cf5ba876239644fb90ab7385bda1cc6 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_i2c.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-04-27 hqfang first implementation. + */ + +#include "drv_i2c.h" + +#ifdef RT_USING_I2C + +#if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1) + #error "Please define at least one BSP_USING_I2Cx" + /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable I2C */ +#endif + +static struct gd32_i2c_config i2c_config[] = +{ +#ifdef BSP_USING_I2C0 + { + "i2c0", + I2C0, + 100000, + }, +#endif +#ifdef BSP_USING_I2C1 + { + "i2c1", + I2C1, + 100000, + }, +#endif +}; + +static struct gd32_i2c i2c_obj[sizeof(i2c_config) / sizeof(i2c_config[0])] = {0}; + +#define GD32_I2C_TIMEOUT 10 + +static int gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint16_t slave_address, rt_uint8_t *p_buffer, rt_uint16_t cnt) +{ + /* send slave address to I2C bus */ + i2c_master_addressing(i2c_periph, slave_address << 1, I2C_RECEIVER); + + /* wait until ADDSEND bit is set */ + while (!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND)); + + /* clear the ADDSEND bit */ + i2c_flag_clear(i2c_periph, I2C_FLAG_ADDSEND); + + /* while there is data to be read */ + while (cnt) + { + if (cnt == 1) + { + // Send NACK for last 1 byte receive + i2c_ack_config(i2c_periph, I2C_ACK_DISABLE); + } + /* wait until the RBNE bit is set */ + while (i2c_flag_get(i2c_periph, I2C_FLAG_RBNE) == RESET); + + /* read a byte from i2c */ + *p_buffer = i2c_data_receive(i2c_periph); + + /* point to the next location where the byte read will be saved */ + p_buffer++; + + /* decrement the read bytes counter */ + cnt--; + } + + return 0; +} + +static int gd32_i2c_write(rt_uint32_t i2c_periph, uint16_t slave_address, uint8_t *p_buffer, uint16_t cnt) +{ + /* send slave address to I2C bus */ + i2c_master_addressing(i2c_periph, slave_address << 1, I2C_TRANSMITTER); + + /* wait until ADDSEND bit is set */ + while (!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND)); + + /* clear the ADDSEND bit */ + i2c_flag_clear(i2c_periph, I2C_FLAG_ADDSEND); + + /* wait until the transmit data buffer is empty */ + while (SET != i2c_flag_get(i2c_periph, I2C_FLAG_TBE)); + + /* while there is data to be read */ + while (cnt) + { + i2c_data_transmit(i2c_periph, *p_buffer); + + /* point to the next byte to be written */ + p_buffer++; + + /* decrement the write bytes counter */ + cnt--; + + /* wait until BTC bit is set */ + while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)); + } + + return 0; +} + +static void gd32_i2c_configure(struct gd32_i2c_config *i2c_cfg) +{ + RT_ASSERT(i2c_cfg != RT_NULL); + + /* configure i2c speed to 100Khz */ + i2c_clock_config(i2c_cfg->i2c_periph, i2c_cfg->speed, I2C_DTCY_2); + /* enable I2C */ + i2c_enable(i2c_cfg->i2c_periph); + /* enable acknowledge */ + i2c_ack_config(i2c_cfg->i2c_periph, I2C_ACK_ENABLE); +} + + +static rt_size_t gd32_i2c_xfer(struct rt_i2c_bus_device *device, struct rt_i2c_msg msgs[], rt_uint32_t num) +{ + struct rt_i2c_msg *msg; + rt_uint32_t i; + rt_err_t ret = RT_ERROR; + rt_uint16_t last_flags; + + RT_ASSERT(device != RT_NULL); + + struct gd32_i2c *i2c_obj = (struct gd32_i2c *)(device); + struct gd32_i2c_config *i2c_cfg = (struct gd32_i2c_config *)(i2c_obj->config); + RT_ASSERT(i2c_cfg != RT_NULL); + + /* wait until I2C bus is idle */ + while (i2c_flag_get(i2c_cfg->i2c_periph, I2C_FLAG_I2CBSY)); + + if (num) + { + if (msg[0].flags & RT_I2C_ADDR_10BIT) + { + i2c_mode_addr_config(i2c_cfg->i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_10BITS, 0x82); + } + else + { + i2c_mode_addr_config(i2c_cfg->i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x82); + } + } + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + + if (!(msg->flags & RT_I2C_NO_START)) + { + /* send a start condition to I2C bus */ + i2c_start_on_bus(i2c_cfg->i2c_periph); + /* wait until SBSEND bit is set */ + while (!i2c_flag_get(i2c_cfg->i2c_periph, I2C_FLAG_SBSEND)); + } + + if (msg->flags & RT_I2C_RD) + { + gd32_i2c_read(i2c_cfg->i2c_periph, msg->addr, msg->buf, msg->len); + } + else + { + gd32_i2c_write(i2c_cfg->i2c_periph, msg->addr, msg->buf, msg->len); + } + } + + if (num) + { + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(i2c_cfg->i2c_periph); + + /* wait until the stop condition is finished */ + while (I2C_CTL0(i2c_cfg->i2c_periph) & I2C_CTL0_STOP); + } + i2c_ack_config(i2c_cfg->i2c_periph, I2C_ACK_ENABLE); + + ret = i; + + return ret; +} + +static const struct rt_i2c_bus_device_ops i2c_ops = +{ + gd32_i2c_xfer, + RT_NULL, + RT_NULL +}; + +int rt_hw_i2c_init(void) +{ + rt_size_t obj_num; + int index; + rt_err_t result = 0; + +#ifdef BSP_USING_I2C0 + rcu_periph_clock_enable(RCU_I2C0); +#endif +#ifdef BSP_USING_I2C1 + rcu_periph_clock_enable(RCU_I2C1); +#endif + + obj_num = sizeof(i2c_obj) / sizeof(struct gd32_i2c); + for (index = 0; index < obj_num; index++) + { + /* init i2c object */ + i2c_obj[index].config = &i2c_config[index]; + i2c_obj[index].bus.ops = &i2c_ops; + + /* init i2c device */ + gd32_i2c_configure(&i2c_config[index]); + + /* register i2c device */ + result = rt_i2c_bus_device_register(&i2c_obj[index].bus, + i2c_obj[index].config->name + ); + RT_ASSERT(result == RT_EOK); + } + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_i2c_init); + +#endif +/* end of i2c driver */ diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_i2c.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..a336b5656e002da673a97e6a8ae28b2864c85c2a --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_i2c.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-04-27 hqfang first implementation. + */ + +#ifndef __DRV_I2C__ +#define __DRV_I2C__ + +#include +#include +#include +#include + +/* gd32 config class */ +struct gd32_i2c_config +{ + const char *name; + rt_uint32_t i2c_periph; + rt_uint32_t speed; +}; + +struct gd32_i2c +{ + struct rt_i2c_bus_device bus; + struct gd32_i2c_config *config; +}; + +#endif diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_pwm.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..b7af639c53978cada838d110473dd23d0d7df883 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_pwm.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-02 hqfang first version + */ + +#include "drv_pwm.h" +// #define DBG_LVL DBG_INFO + +#include + +#ifdef BSP_USING_PWM + +#if !defined(BSP_USING_PWM0) && !defined(BSP_USING_PWM1) && !defined(BSP_USING_PWM2) \ + && !defined(BSP_USING_PWM3) && !defined(BSP_USING_PWM4) + #error "Please define at least one BSP_USING_PWMx" + /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable PWM */ +#endif + +static struct gd32_pwm_config pwm_config[] = +{ +#ifdef BSP_USING_PWM0 + { + "pwm0", + TIMER0, + 1000000, + }, +#endif +#ifdef BSP_USING_PWM1 + { + "pwm1", + TIMER1, + 1000000, + }, +#endif +#ifdef BSP_USING_PWM2 + { + "pwm2", + TIMER2, + 1000000, + }, +#endif +#ifdef BSP_USING_PWM3 + { + "pwm3", + TIMER3, + 1000000, + }, +#endif +#ifdef BSP_USING_PWM4 + { + "pwm4", + TIMER4, + 1000000, + }, +#endif +}; + +#define GD32_MAX_PWM_CHANNELS TIMER_CH_3 +static struct gd32_pwm pwm_obj[sizeof(pwm_config) / sizeof(pwm_config[0])] = {0}; + +static rt_err_t gd32_pwm_enable(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration, rt_bool_t enable) +{ + struct gd32_pwm_config *config; + config = (struct gd32_pwm_config *)device->parent.user_data; + RT_ASSERT(config); + + if (configuration->channel > GD32_MAX_PWM_CHANNELS) + { + return RT_EINVAL; + } + if (!enable) + { + timer_channel_output_state_config(config->periph, configuration->channel, TIMER_CCX_DISABLE); + } + else + { + timer_channel_output_state_config(config->periph, configuration->channel, TIMER_CCX_ENABLE); + } + + return RT_EOK; +} + +static uint32_t gd32_get_pwm_clk(rt_uint32_t periph) +{ + uint32_t clk; + uint8_t clkpre; + if (periph != TIMER0) + { + clk = rcu_clock_freq_get(CK_APB1); + clkpre = GET_BITS(RCU_CFG0, 8, 10); + } + else + { + clk = rcu_clock_freq_get(CK_APB2); + clkpre = GET_BITS(RCU_CFG0, 11, 13); + } + if (clkpre >= 4) + { + clk = clk * 2; + } + return clk; +} + +static rt_err_t gd32_pwm_get(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration) +{ + uint32_t pwmclk; + uint16_t prescale, period, clkdiv, pulse; + struct gd32_pwm_config *config; + config = (struct gd32_pwm_config *)device->parent.user_data; + RT_ASSERT(config); + + pwmclk = gd32_get_pwm_clk(config->periph); + prescale = (uint16_t)TIMER_PSC(config->periph) + 1; + clkdiv = ((uint16_t)(TIMER_CTL0(config->periph) & TIMER_CTL0_CKDIV) >> 8); + clkdiv = 1 << clkdiv; + period = (uint16_t)TIMER_CAR(config->periph) + 1; + pulse = (uint16_t)REG32((config->periph) + 0x34U + configuration->channel << 2) + 1; + + pwmclk = pwmclk / prescale / clkdiv; + LOG_I("current pwmclk is %d\n", pwmclk); + + configuration->period = (uint64_t)period * 1000000000 / pwmclk; + configuration->pulse = (uint64_t)pulse * 1000000000 / pwmclk; + return RT_EOK; +} + +static rt_err_t gd32_pwm_set(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration) +{ + timer_oc_parameter_struct timer_ocinitpara; + timer_parameter_struct timer_initpara; + uint32_t pwmclk, pwmclkv2; + uint64_t period_cmp; + uint16_t prescale, period, clkdiv, pulse; + struct gd32_pwm_config *config; + config = (struct gd32_pwm_config *)device->parent.user_data; + RT_ASSERT(config); + + if (configuration->channel > GD32_MAX_PWM_CHANNELS) + { + LOG_I("max channel supported is %d\n", GD32_MAX_PWM_CHANNELS); + return RT_EINVAL; + } + if (configuration->period < configuration->pulse) + { + LOG_I("period should > pulse \n"); + return RT_EINVAL; + } + + pwmclk = gd32_get_pwm_clk(config->periph); + + // min period value >= 100 + period_cmp = (uint64_t)(1000000000 / pwmclk) * 10; + if (configuration->period < period_cmp) + { + return RT_EINVAL; + } + period_cmp = (uint64_t)(1000000000 / (pwmclk / 65536 / 4)) * 65536; + if (configuration->period > period_cmp) + { + return RT_EINVAL; + } + + period_cmp = (uint64_t) pwmclk * configuration->period / 1000000000; + + if (period_cmp < 65536) + { + prescale = 0; + clkdiv = TIMER_CKDIV_DIV1; + period = period_cmp; + } + else if (period_cmp < 4294967296) + { + prescale = period_cmp / 65536; + period = period_cmp / (prescale + 1); + clkdiv = TIMER_CKDIV_DIV1; + } + else if (period_cmp < 8589934592) + { + prescale = period_cmp / 65536; + period = period_cmp / (prescale + 1) / 2; + clkdiv = TIMER_CKDIV_DIV2; + } + else + { + prescale = period_cmp / 65536; + period = period_cmp / (prescale + 1) / 4; + clkdiv = TIMER_CKDIV_DIV4; + } + + pwmclkv2 = pwmclk / (prescale + 1) / (1 << clkdiv); + LOG_I("current pwmclk is %d\n", pwmclkv2); + + LOG_I("Set channel %d, period %dns, pulse %dns\n", configuration->channel, \ + configuration->period, configuration->pulse); + pulse = (uint64_t)period * configuration->pulse / configuration->period; + LOG_I("pwmclk %d, pwmcmp %d, prescale %d, period %d, pulse %d, clkdiv %d\n", \ + pwmclk, (uint32_t)period_cmp, prescale, period, pulse, clkdiv); + + /* initialize TIMER init parameter struct */ + timer_struct_para_init(&timer_initpara); + /* TIMER configuration */ + timer_initpara.prescaler = prescale; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = period; + timer_initpara.clockdivision = clkdiv; + timer_initpara.repetitioncounter = 0; + timer_init(config->periph, &timer_initpara); + + /* initialize TIMER channel output parameter struct */ + timer_channel_output_struct_para_init(&timer_ocinitpara); + /* CH0, CH1 and CH2 configuration in PWM mode */ + timer_ocinitpara.outputstate = TIMER_CCX_DISABLE; + timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + + timer_channel_output_config(config->periph, configuration->channel, &timer_ocinitpara); + + /* Channel configuration in PWM mode */ + timer_channel_output_pulse_value_config(config->periph, configuration->channel, pulse); + timer_channel_output_mode_config(config->periph, configuration->channel, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(config->periph, configuration->channel, TIMER_OC_SHADOW_DISABLE); + + timer_primary_output_config(config->periph, ENABLE); + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(config->periph); + timer_enable(config->periph); + + return RT_EOK; +} + +static rt_err_t gd32_pwm_control(struct rt_device_pwm *device, int cmd, void *arg) +{ + struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg; + + switch (cmd) + { + case PWM_CMD_ENABLE: + return gd32_pwm_enable(device, configuration, RT_TRUE); + case PWM_CMD_DISABLE: + return gd32_pwm_enable(device, configuration, RT_FALSE); + case PWM_CMD_SET: + return gd32_pwm_set(device, configuration); + case PWM_CMD_GET: + return gd32_pwm_get(device, configuration); + default: + return RT_EINVAL; + } +} + +static rt_err_t gd32_pwm_init(struct gd32_pwm_config *config) +{ + timer_oc_parameter_struct timer_ocinitpara; + timer_parameter_struct timer_initpara; + uint32_t pwmclk; + uint16_t prescale; + + pwmclk = gd32_get_pwm_clk(config->periph); + + /* period 1ms, duty 50% */ + prescale = pwmclk / 1000 / 1000 - 1; + + config->period = 1000000; + + LOG_I("pwmclk %d, prescale %d, period %d, clkdiv %d\n", pwmclk, prescale, 999, 0); + + /* initialize TIMER init parameter struct */ + timer_struct_para_init(&timer_initpara); + /* TIMER configuration */ + timer_initpara.prescaler = prescale; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(config->periph, &timer_initpara); + + /* initialize TIMER channel output parameter struct */ + timer_channel_output_struct_para_init(&timer_ocinitpara); + /* CH0, CH1 and CH2 configuration in PWM mode */ + timer_ocinitpara.outputstate = TIMER_CCX_DISABLE; + timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + + /* Channel configuration in PWM mode */ + for (int i = 0; i <= GD32_MAX_PWM_CHANNELS; i ++) + { + timer_channel_output_config(config->periph, i, &timer_ocinitpara); + timer_channel_output_pulse_value_config(config->periph, i, 499); + timer_channel_output_mode_config(config->periph, i, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(config->periph, i, TIMER_OC_SHADOW_DISABLE); + } + + timer_primary_output_config(config->periph, ENABLE); + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(config->periph); + timer_enable(config->periph); + + return RT_EOK; +} + +static struct rt_pwm_ops gd32_drv_ops = +{ + .control = gd32_pwm_control +}; + +static int rt_pwm_init(void) +{ + int i = 0; + int result = RT_EOK; + +#ifdef BSP_USING_PWM0 + rcu_periph_clock_enable(RCU_TIMER0); +#endif +#ifdef BSP_USING_PWM1 + rcu_periph_clock_enable(RCU_TIMER1); +#endif +#ifdef BSP_USING_PWM2 + rcu_periph_clock_enable(RCU_TIMER2); +#endif +#ifdef BSP_USING_PWM3 + rcu_periph_clock_enable(RCU_TIMER3); +#endif +#ifdef BSP_USING_PWM4 + rcu_periph_clock_enable(RCU_TIMER4); +#endif + rcu_periph_clock_enable(RCU_AF); + + for (i = 0; i < sizeof(pwm_obj) / sizeof(pwm_obj[0]); i++) + { + pwm_obj[i].config = &pwm_config[i]; + rt_device_pwm_register(&pwm_obj[i].pwm_device, pwm_config[i].name, &gd32_drv_ops, pwm_obj[i].config); + gd32_pwm_init(&pwm_config[i]); + } + + return result; +} + +INIT_DEVICE_EXPORT(rt_pwm_init); + +#endif /* RT_USING_PWM */ diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_pwm.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..c0c64232632ef7743a50688b7ea768d250ffe665 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_pwm.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2029-06-02 hqfang first implementation. + */ + +#ifndef __DRV_PWM__ +#define __DRV_PWM__ + +#include +#include +#include +#include + +/* gd32 config class */ +struct gd32_pwm_config +{ + const char *name; + rt_uint32_t periph; + rt_uint32_t period; + rt_uint32_t pulse; +}; + +struct gd32_pwm +{ + struct rt_device_pwm pwm_device; + struct gd32_pwm_config *config; +}; + +#endif diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_rtc.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..1d1c5ced78fa7727be799279c2314d3afcec171f --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_rtc.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-08 hqfang first implementation. + */ + +#include "drv_rtc.h" + +#ifdef BSP_USING_RTC + +static time_t get_timestamp(void) +{ + return (time_t)rtc_counter_get(); +} + +static int set_timestamp(time_t timestamp) +{ + /* wait until last write operation on RTC registers has finished */ + rtc_lwoff_wait(); + /* change the current time */ + rtc_counter_set((uint32_t)timestamp); + /* wait until last write operation on RTC registers has finished */ + rtc_lwoff_wait(); + return RT_EOK; +} + +static void rtc_configuration(void) +{ + /* enable PMU and BKPI clocks */ + rcu_periph_clock_enable(RCU_BKPI); + rcu_periph_clock_enable(RCU_PMU); + /* allow access to BKP domain */ + pmu_backup_write_enable(); + + /* reset backup domain */ + bkp_deinit(); + + /* enable LXTAL */ + rcu_osci_on(RCU_LXTAL); + /* wait till LXTAL is ready */ + rcu_osci_stab_wait(RCU_LXTAL); + + /* select RCU_LXTAL as RTC clock source */ + rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); + + /* enable RTC Clock */ + rcu_periph_clock_enable(RCU_RTC); + + /* wait for RTC registers synchronization */ + rtc_register_sync_wait(); + + /* wait until last write operation on RTC registers has finished */ + rtc_lwoff_wait(); + + /* wait until last write operation on RTC registers has finished */ + rtc_lwoff_wait(); + + /* set RTC prescaler: set RTC period to 1s */ + rtc_prescaler_set(32767); + + /* wait until last write operation on RTC registers has finished */ + rtc_lwoff_wait(); +} + +static rt_err_t gd32_rtc_init(rt_device_t dev) +{ + if (bkp_data_read(BKP_DATA_0) != 0xA5A5) + { + rtc_configuration(); + bkp_data_write(BKP_DATA_0, 0xA5A5); + } + else + { + /* allow access to BKP domain */ + rcu_periph_clock_enable(RCU_PMU); + pmu_backup_write_enable(); + + /* wait for RTC registers synchronization */ + rtc_register_sync_wait(); + /* wait until last write operation on RTC registers has finished */ + rtc_lwoff_wait(); + } + + return RT_EOK; +} + +static rt_err_t gd32_rtc_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t gd32_rtc_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_size_t gd32_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + return RT_EOK; +} + +static rt_size_t gd32_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + return RT_EOK; +} + +static rt_err_t gd32_rtc_control(rt_device_t dev, int cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + { + *(uint32_t *)args = get_timestamp(); + } + break; + + case RT_DEVICE_CTRL_RTC_SET_TIME: + { + set_timestamp(*(time_t *)args); + } + break; + + default: + return RT_EINVAL; + } + + return RT_EOK; +} + +static struct rt_device rtc_device = +{ + .type = RT_Device_Class_RTC, + .init = gd32_rtc_init, + .open = gd32_rtc_open, + .close = gd32_rtc_close, + .read = gd32_rtc_read, + .write = gd32_rtc_write, + .control = gd32_rtc_control, +}; + +int rt_hw_rtc_init(void) +{ + rt_err_t ret = RT_EOK; + + ret = rt_device_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR); + + rt_device_open(&rtc_device, RT_DEVICE_OFLAG_RDWR); + + return RT_EOK; +} + +INIT_DEVICE_EXPORT(rt_hw_rtc_init); + +#endif /* BSP_USING_RTC */ diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_rtc.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..ae17cde802f2e5c52eb9a664e65485514db17b2d --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_rtc.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-08 hqfang first implementation. + */ + +#ifndef DRV_RTC_H__ +#define DRV_RTC_H__ + +#include +#include +#include +#include + +#endif diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_spi.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..bcdaacb47ba191ab006e336bfead22ddad2d9cd4 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_spi.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-05-28 hqfang first implementation. + */ + +#include "drv_spi.h" + +#ifdef RT_USING_SPI + +#if !defined(BSP_USING_SPI0) && !defined(BSP_USING_SPI1) && !defined(BSP_USING_SPI2) + #error "Please define at least one BSP_USING_SPIx" + /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable SPI */ +#endif + +static struct gd32_spi_config spi_config[] = +{ +#ifdef BSP_USING_SPI0 + { + "spi0", + SPI0, + }, +#endif +#ifdef BSP_USING_SPI1 + { + "spi1", + SPI1, + }, +#endif +#ifdef BSP_USING_SPI2 + { + "spi2", + SPI2, + }, +#endif +}; + +static struct gd32_spi spi_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0}; + +static rt_err_t gd32_spi_init(rt_uint32_t spi_periph, struct rt_spi_configuration *cfg) +{ + spi_parameter_struct spicfg; + uint32_t apbfreq; + uint32_t scale; + + RT_ASSERT(cfg != RT_NULL); + + spi_struct_para_init(&spicfg); + + if (cfg->data_width != 8 && cfg->data_width != 16) + { + return (-RT_EINVAL); + } + + switch (spi_periph) + { + case SPI0: + apbfreq = rcu_clock_freq_get(CK_APB2); + break; + default: + apbfreq = rcu_clock_freq_get(CK_APB1); + break; + } + + scale = apbfreq / cfg->max_hz; + if (scale <= 2) + { + spicfg.prescale = SPI_PSC_2; + } + else if (scale <= 4) + { + spicfg.prescale = SPI_PSC_4; + } + else if (scale <= 8) + { + spicfg.prescale = SPI_PSC_8; + } + else if (scale <= 16) + { + spicfg.prescale = SPI_PSC_16; + } + else if (scale <= 32) + { + spicfg.prescale = SPI_PSC_32; + } + else if (scale <= 64) + { + spicfg.prescale = SPI_PSC_64; + } + else if (scale <= 128) + { + spicfg.prescale = SPI_PSC_128; + } + else if (scale <= 256) + { + spicfg.prescale = SPI_PSC_256; + } + else + { + spicfg.prescale = SPI_PSC_256; + } + + if (cfg->data_width == 8) + { + spicfg.frame_size = SPI_FRAMESIZE_8BIT; + } + else + { + spicfg.frame_size = SPI_FRAMESIZE_16BIT; + } + + if (cfg->mode & RT_SPI_MSB) + { + spicfg.endian = SPI_ENDIAN_MSB; + } + else + { + spicfg.endian = SPI_ENDIAN_LSB; + } + + spicfg.clock_polarity_phase = 0; + if (cfg->mode & RT_SPI_CPHA) + { + spicfg.clock_polarity_phase |= SPI_CTL0_CKPH; + } + if (cfg->mode & RT_SPI_CPOL) + { + spicfg.clock_polarity_phase |= SPI_CTL0_CKPL; + } + + if (cfg->mode & RT_SPI_SLAVE) + { + spicfg.device_mode = SPI_SLAVE; + } + else + { + spicfg.device_mode = SPI_MASTER; + } + spicfg.nss = SPI_NSS_SOFT; + spicfg.trans_mode = SPI_TRANSMODE_FULLDUPLEX; + + spi_init(spi_periph, &spicfg); + /* set crc polynomial */ + spi_crc_polynomial_set(spi_periph, 7); + + return RT_EOK; +} + +static rt_err_t gd32_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg) +{ + rt_err_t ret = RT_EOK; + RT_ASSERT(device != RT_NULL); + + struct gd32_spi *spi_obj = (struct gd32_spi *)(device->bus->parent.user_data); + struct gd32_spi_config *spi_cfg = (struct gd32_spi_config *)(spi_obj->config); + + ret = gd32_spi_init(spi_cfg->spi_periph, cfg); + /* enable SPI */ + spi_enable(spi_cfg->spi_periph); + + return ret; +} + +/** + * Attach the spi device to SPI bus, this function must be used after initialization. + */ +rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin) +{ + rt_err_t ret = RT_EOK; + + struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device)); + RT_ASSERT(spi_device != RT_NULL); + + struct gd32_spi_cs *cs_pin = (struct gd32_spi_cs *)rt_malloc(sizeof(struct gd32_spi_cs)); + RT_ASSERT(cs_pin != RT_NULL); + + cs_pin->pin = pin; + rt_pin_mode(pin, PIN_MODE_OUTPUT); + rt_pin_write(pin, PIN_HIGH); + + ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin); + + return ret; +} + +rt_size_t gd32_spi_transmit(rt_uint32_t spi_periph, const void *send_buf, void *recv_buf, rt_size_t length) +{ + uint8_t *send_buf_8b = (uint8_t *)send_buf; + uint8_t *recv_buf_8b = (uint8_t *)recv_buf; + uint8_t sndbyte = 0xFF, rcvbyte; + rt_size_t idx = 0; + + while (idx < length) + { + while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); + if (send_buf_8b) + { + sndbyte = send_buf_8b[idx]; + } + spi_i2s_data_transmit(spi_periph, sndbyte); + while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); + rcvbyte = spi_i2s_data_receive(spi_periph); + if (recv_buf_8b) + { + recv_buf_8b[idx] = rcvbyte; + } + idx ++; + } + + return length; +} + +static rt_uint32_t gd32_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + rt_uint32_t total_length = 0; + rt_err_t ret = RT_EOK; + + RT_ASSERT(device != RT_NULL); + + struct gd32_spi *spi_obj = (struct gd32_spi *)(device->bus->parent.user_data); + struct gd32_spi_config *spi_cfg = (struct gd32_spi_config *)(spi_obj->config); + RT_ASSERT(spi_cfg != RT_NULL); + struct gd32_spi_cs *cs = (struct gd32_spi_cs *)(device->parent.user_data); + + if (message && message->cs_take) + { + rt_pin_write(cs->pin, PIN_LOW); + } + if (message && message->length) + { + + total_length += gd32_spi_transmit(spi_cfg->spi_periph, message->send_buf, \ + message->recv_buf, message->length); + } + if (message && message->cs_release) + { + rt_pin_write(cs->pin, PIN_HIGH); + } + return total_length; +} + +static const struct rt_spi_ops spi_ops = +{ + gd32_spi_configure, + gd32_spi_xfer +}; + +int rt_hw_spi_init(void) +{ + rt_size_t obj_num; + int index; + rt_err_t result = 0; + +#ifdef BSP_USING_SPI0 + rcu_periph_clock_enable(RCU_SPI0); +#endif +#ifdef BSP_USING_SPI1 + rcu_periph_clock_enable(RCU_SPI1); +#endif +#ifdef BSP_USING_SPI2 + rcu_periph_clock_enable(RCU_SPI2); +#endif + + obj_num = sizeof(spi_obj) / sizeof(struct gd32_spi); + for (index = 0; index < obj_num; index++) + { + /* init spi object */ + spi_obj[index].config = &spi_config[index]; + spi_obj[index].bus.parent.user_data = &spi_obj[index]; + + /* register spi device */ + result = rt_spi_bus_register(&spi_obj[index].bus, + spi_obj[index].config->name, + &spi_ops); + RT_ASSERT(result == RT_EOK); + } + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_spi_init); + +#endif +/* end of spi driver */ diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_spi.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..a38f5c40c452d3a4541d4cb6d196caec198dd9c2 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_spi.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2029-04-29 hqfang first implementation. + */ + +#ifndef __DRV_SPI__ +#define __DRV_SPI__ + +#include +#include +#include +#include + +/* gd32 config class */ +struct gd32_spi_config +{ + const char *name; + rt_uint32_t spi_periph; +}; + +struct gd32_spi_cs +{ + rt_uint32_t pin; +}; + +struct gd32_spi +{ + struct rt_spi_bus bus; + struct gd32_spi_config *config; +}; + +int rt_hw_spi_init(void); +rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin); + +#endif diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.c index 00fac33b3ee272979a5d0c2c8deb8b4a440ee4d6..8b729abd8f785eba511d0583dde3d82cf20599fa 100644 --- a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.c +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.c @@ -16,7 +16,7 @@ #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) \ && !defined(BSP_USING_UART3) && !defined(BSP_USING_UART4) #error "Please define at least one BSP_USING_UARTx" - /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */ + /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable UART */ #endif enum @@ -64,8 +64,8 @@ static struct gd32_uart_config uart_config[] = #ifdef BSP_USING_UART3 { "uart3", - USART3, - USART3_IRQn, + UART3, + UART3_IRQn, }, #endif #ifdef BSP_USING_UART4 @@ -137,7 +137,7 @@ static rt_err_t gd32_configure(struct rt_serial_device *serial, break; } usart_hardware_flow_rts_config(usart->uart_base, USART_RTS_DISABLE); - usart_hardware_flow_cts_config(usart->uart_base, USART_RTS_DISABLE); + usart_hardware_flow_cts_config(usart->uart_base, USART_CTS_DISABLE); usart_receive_config(usart->uart_base, USART_RECEIVE_ENABLE); usart_transmit_config(usart->uart_base, USART_TRANSMIT_ENABLE); usart_enable(usart->uart_base); @@ -320,6 +320,22 @@ int rt_hw_usart_init(void) rt_size_t obj_num; int index; +#ifdef BSP_USING_UART0 + rcu_periph_clock_enable(RCU_USART0); +#endif +#ifdef BSP_USING_UART1 + rcu_periph_clock_enable(RCU_USART1); +#endif +#ifdef BSP_USING_UART2 + rcu_periph_clock_enable(RCU_USART2); +#endif +#ifdef BSP_USING_UART3 + rcu_periph_clock_enable(RCU_UART3); +#endif +#ifdef BSP_USING_UART4 + rcu_periph_clock_enable(RCU_UART4); +#endif + obj_num = sizeof(uart_obj) / sizeof(struct gd32_uart); struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; rt_err_t result = 0; diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.h index 176720c4a2da8af1d7f58c4f27e2b42a8e41dc60..00b285847cad77c9c78f5e99a299af7da7d7e921 100644 --- a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.h +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.h @@ -25,8 +25,8 @@ struct gd32_uart_config /* gd32 uart dirver class */ struct gd32_uart { - struct gd32_uart_config *config; struct rt_serial_device serial; + struct gd32_uart_config *config; }; int rt_hw_usart_init(void); diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_wdt.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_wdt.c new file mode 100644 index 0000000000000000000000000000000000000000..f0b340edac4caeecc703a8cf454dfc11c7e350b1 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_wdt.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-08 hqfang the first version. + * + */ +#include "drv_wdt.h" + +#ifdef BSP_USING_WDT + + +static rt_err_t gd32_wdog_close(rt_watchdog_t *wdt) +{ + rt_uint32_t level; + + level = rt_hw_interrupt_disable(); + rcu_osci_off(RCU_IRC40K); + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +static rt_err_t gd32_wdog_open(rt_watchdog_t *wdt, rt_uint16_t oflag) +{ + rt_uint32_t level; + + level = rt_hw_interrupt_disable(); + /* enable IRC40K */ + rcu_osci_on(RCU_IRC40K); + /* wait till IRC40K is ready */ + while (SUCCESS != rcu_osci_stab_wait(RCU_IRC40K)); + fwdgt_counter_reload(); + fwdgt_enable(); + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +static rt_err_t gd32_wdog_init(rt_watchdog_t *wdt) +{ + /* confiure FWDGT counter clock: 40KHz(IRC40K) / 256 = 0.15625 KHz */ + fwdgt_config(FWDGT_RLD_RLD, FWDGT_PSC_DIV256); + fwdgt_enable(); + return RT_EOK; +} + +static rt_err_t gd32_wdog_refresh(rt_watchdog_t *wdt) +{ + rt_uint32_t level; + + level = rt_hw_interrupt_disable(); + fwdgt_counter_reload(); + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +/** + * @function control wdog + * + * @param + * wdt whick wdog used + * cmd control wdog options + * args argument of conrtol + * @retval rt_err_t the status of control result + * + * + */ +#define WDT_RELOAD_SECOND ((FWDGT_RLD & FWDGT_RLD_RLD) / 156) +static rt_err_t gd32_wdog_control(rt_watchdog_t *wdt, int cmd, void *args) +{ + RT_ASSERT(wdt != NULL); + + uint16_t reload_value; + static uint16_t wdt_started = 0; + static rt_tick_t last_tick = 0; + + switch (cmd) + { + case RT_DEVICE_CTRL_WDT_GET_TIMEOUT: + { + *(uint16_t *)args = WDT_RELOAD_SECOND; + } + break; + case RT_DEVICE_CTRL_WDT_SET_TIMEOUT: + { + RT_ASSERT(*(uint16_t *)args != 0); + reload_value = *(uint16_t *)args; + // 6.4ms 1 tick, 1s -> 1000 / 6.4 = 625 / 4 ticks + reload_value = ((uint32_t)reload_value * 625) / 4; + fwdgt_write_enable(); + while (FWDGT_STAT & FWDGT_STAT_RUD); + FWDGT_RLD = FWDGT_RLD_RLD & reload_value; + fwdgt_write_disable(); + } + break; + case RT_DEVICE_CTRL_WDT_GET_TIMELEFT: + *(uint16_t *)args = WDT_RELOAD_SECOND - \ + (rt_tick_get() - last_tick) / RT_TICK_PER_SECOND; + + break; + case RT_DEVICE_CTRL_WDT_KEEPALIVE: + { + last_tick = rt_tick_get(); + gd32_wdog_refresh(wdt); + } + break; + case RT_DEVICE_CTRL_WDT_START: + { + gd32_wdog_open(wdt, *(rt_uint32_t *)args); + last_tick = rt_tick_get(); + wdt_started = 1; + while (FWDGT_STAT & FWDGT_STAT_RUD); + } + break; + case RT_DEVICE_CTRL_WDT_STOP: + { + gd32_wdog_close(wdt); + wdt_started = 0; + } + break; + default: + return RT_EINVAL; + } + + return RT_EOK; +} + +static struct rt_watchdog_ops gd32_wdog_ops = +{ + .init = gd32_wdog_init, + .control = gd32_wdog_control, +}; + +static struct rt_watchdog_device gd32_wdt_device; + +int rt_hw_wdt_init(void) +{ + int result = RT_EOK; + + rcu_osci_off(RCU_IRC40K); + gd32_wdt_device.ops = &gd32_wdog_ops; + result = rt_hw_watchdog_register(&gd32_wdt_device, "wdt", \ + RT_DEVICE_FLAG_RDWR, (void *)FWDGT); + + return result; +} + +INIT_DEVICE_EXPORT(rt_hw_wdt_init); + +#endif /* BSP_USING_WDT */ + diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_wdt.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..9c279dc5d48c2182ff8ea5732ec2263b4eff8aa2 --- /dev/null +++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_wdt.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2029-06-08 hqfang first implementation. + */ + +#ifndef __DRV_WDT__ +#define __DRV_WDT__ + +#include +#include +#include +#include + + +#endif diff --git a/bsp/nuclei/tools/sdk_dist.py b/bsp/nuclei/tools/sdk_dist.py index f802e92730a7088f244c60a68fcb52f18cf861ca..260f0ee1cfcbc31132f13e8ba51411d38ab35b7d 100644 --- a/bsp/nuclei/tools/sdk_dist.py +++ b/bsp/nuclei/tools/sdk_dist.py @@ -5,11 +5,10 @@ cwd_path = os.getcwd() sys.path.append(os.path.join(os.path.dirname(cwd_path), 'rt-thread', 'tools')) # BSP dist function -def dist_do_building(BSP_ROOT): +def dist_do_building(BSP_ROOT, dist_dir): from mkdist import bsp_copy_files import rtconfig - dist_dir = os.path.join(BSP_ROOT, 'dist', os.path.basename(BSP_ROOT)) library_dir = os.path.join(dist_dir, 'libraries') print("=> copy nuclei bsp library") diff --git a/bsp/raspberry-pi/raspi4-32/.config b/bsp/raspberry-pi/raspi4-32/.config index 67da7a97c64b331663b9ce4d8fc3cf2683133f20..6f7fc20100b800a6784eef0f110d442395001f7d 100644 --- a/bsp/raspberry-pi/raspi4-32/.config +++ b/bsp/raspberry-pi/raspi4-32/.config @@ -65,7 +65,7 @@ CONFIG_RT_USING_DEVICE=y # CONFIG_RT_USING_INTERRUPT_INFO is not set CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 -CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" CONFIG_RT_VER_NUM=0x40003 # CONFIG_RT_USING_CPU_FFS is not set CONFIG_ARCH_ARMV8=y @@ -331,7 +331,6 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_LWEXT4 is not set # CONFIG_PKG_USING_PARTITION is not set # CONFIG_PKG_USING_FAL 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_LITTLEVGL2RTT is not set @@ -388,7 +387,6 @@ CONFIG_RT_USING_POSIX=y # 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 # # miscellaneous packages @@ -425,6 +423,38 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_VT100 is not set # CONFIG_PKG_USING_ULAPACK is not set # CONFIG_PKG_USING_UKAL is not set + +# +# Privated Packages of RealThread +# +# CONFIG_PKG_USING_CODEC is not set +# CONFIG_PKG_USING_PLAYER is not set +# CONFIG_PKG_USING_MPLAYER is not set +# CONFIG_PKG_USING_PERSIMMON_SRC is not set +# CONFIG_PKG_USING_JS_PERSIMMON is not set +# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set + +# +# Network Utilities +# +# CONFIG_PKG_USING_WICED is not set +# CONFIG_PKG_USING_CLOUDSDK is not set +# CONFIG_PKG_USING_POWER_MANAGER is not set +# CONFIG_PKG_USING_RT_OTA is not set +# CONFIG_PKG_USING_RDBD_SRC is not set +# CONFIG_PKG_USING_RTINSIGHT is not set +# CONFIG_PKG_USING_SMARTCONFIG is not set +# CONFIG_PKG_USING_RTX is not set +# CONFIG_RT_USING_TESTCASE is not set +# CONFIG_PKG_USING_NGHTTP2 is not set +# CONFIG_PKG_USING_AVS is not set +# CONFIG_PKG_USING_ALI_LINKKIT is not set +# CONFIG_PKG_USING_STS is not set +# CONFIG_PKG_USING_DLMS is not set +# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set +# CONFIG_PKG_USING_ZBAR is not set +# CONFIG_PKG_USING_MCF is not set +# CONFIG_PKG_USING_URPC is not set CONFIG_BCM2711_SOC=y # CONFIG_BSP_SUPPORT_FPU is not set diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_gpio.c b/bsp/raspberry-pi/raspi4-32/driver/drv_gpio.c index 8b64f7afb50b726caa299ee28176ed7630d34c6d..e342032d55bf7d6131ad929d6be23a20ccf19adf 100644 --- a/bsp/raspberry-pi/raspi4-32/driver/drv_gpio.c +++ b/bsp/raspberry-pi/raspi4-32/driver/drv_gpio.c @@ -6,17 +6,24 @@ * Change Logs: * Date Author Notes * 2020-04-16 bigmagic first version + * 2020-06-16 bigmagic add gpio irq */ #include "drv_gpio.h" #ifdef BSP_USING_PIN -void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode) + +/* + * gpio_int[0] for BANK0 (pins 0-27) + * gpio_int[1] for BANK1 (pins 28-45) + * gpio_int[2] for BANK2 (pins 46-53) + */ +static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM]; + +uint32_t raspi_get_pin_state(uint32_t fselnum) { - uint32_t fselnum = pin / 10; - uint32_t fselrest = pin % 10; uint32_t gpfsel = 0; - + switch (fselnum) { case 0: @@ -40,10 +47,11 @@ void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode) default: break; } + return gpfsel; +} - gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3))); - gpfsel |= (uint32_t)(mode << (fselrest * 3)); - +void raspi_set_pin_state(uint32_t fselnum, uint32_t gpfsel) +{ switch (fselnum) { case 0: @@ -69,9 +77,74 @@ void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode) } } +static void gpio_set_pud(GPIO_PIN pin, GPIO_PUPD_FUNC mode) +{ + uint32_t fselnum = pin / 16; + uint32_t fselrest = pin % 16; + uint32_t reg_value = 0; + + switch (fselnum) + { + case 0: + reg_value = GPIO_PUP_PDN_CNTRL_REG0(GPIO_BASE); + GPIO_PUP_PDN_CNTRL_REG0(GPIO_BASE) = (reg_value | (mode << (fselrest*2))); + break; + case 1: + reg_value = GPIO_PUP_PDN_CNTRL_REG1(GPIO_BASE); + GPIO_PUP_PDN_CNTRL_REG1(GPIO_BASE) = (reg_value | (mode << (fselrest*2))); + break; + + case 2: + reg_value = GPIO_PUP_PDN_CNTRL_REG2(GPIO_BASE); + GPIO_PUP_PDN_CNTRL_REG2(GPIO_BASE) = (reg_value | (mode << (fselrest*2))); + break; + + case 3: + reg_value = GPIO_PUP_PDN_CNTRL_REG3(GPIO_BASE); + GPIO_PUP_PDN_CNTRL_REG3(GPIO_BASE) = (reg_value | (mode << (fselrest*2))); + break; + default: + break; + } +} + +void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode) +{ + uint32_t fselnum = pin / 10; + uint32_t fselrest = pin % 10; + uint32_t gpfsel = 0; + + gpfsel = raspi_get_pin_state(fselnum); + gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3))); + gpfsel |= (uint32_t)(mode << (fselrest * 3)); + raspi_set_pin_state(fselnum, gpfsel); +} + static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode) { - prev_raspi_pin_mode((GPIO_PIN)pin, (GPIO_FUNC)mode); + GPIO_FUNC raspi_mode = OUTPUT; + + switch (mode) + { + case PIN_MODE_OUTPUT: + raspi_mode = OUTPUT; + break; + case PIN_MODE_INPUT: + raspi_mode = INPUT; + break; + case PIN_MODE_INPUT_PULLUP: + gpio_set_pud(pin, RASPI_PULL_UP); + raspi_mode = INPUT; + break; + case PIN_MODE_INPUT_PULLDOWN: + gpio_set_pud(pin, RASPI_PULL_DOWN); + raspi_mode = INPUT; + break; + case PIN_MODE_OUTPUT_OD: + raspi_mode = OUTPUT; + break; + } + prev_raspi_pin_mode((GPIO_PIN)pin, raspi_mode); } static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value) @@ -99,27 +172,162 @@ static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t valu { GPIO_REG_GPCLR1(GPIO_BASE) = 1 << (pin % 32); } - } } static int raspi_pin_read(struct rt_device *device, rt_base_t pin) { - return 0; + uint32_t num = pin / 32; + uint32_t pin_level = 0; + + if(num == 0) + { + if(GPIO_REG_GPLEV0(GPIO_BASE) & (1 << pin)) + { + pin_level = 1; + } + else + { + pin_level = 0; + } + + } + else + { + if(GPIO_REG_GPLEV1(GPIO_BASE) & (1 << pin)) + { + pin_level = 1; + } + else + { + pin_level = 0; + } + } + + return pin_level; } static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) { + rt_uint8_t index; + rt_uint32_t reg_value; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + _g_gpio_irq_tbl[index].irq_cb[pin] = hdr; + _g_gpio_irq_tbl[index].irq_arg[pin] = args; + _g_gpio_irq_tbl[index].irq_type[pin] = mode; + + rt_uint8_t shift = pin % 32; + rt_uint8_t pin_num = pin / 32; + rt_uint32_t mask = 1 << shift; + + switch (mode) + { + case PIN_IRQ_MODE_RISING: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPREN0(GPIO_BASE); + GPIO_REG_GPREN0(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPREN1(GPIO_BASE); + GPIO_REG_GPREN1(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + break; + case PIN_IRQ_MODE_FALLING: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPFEN0(GPIO_BASE); + GPIO_REG_GPFEN0(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPFEN1(GPIO_BASE); + GPIO_REG_GPFEN1(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + break; + case PIN_IRQ_MODE_RISING_FALLING: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPAREN0(GPIO_BASE); + GPIO_REG_GPAREN0(GPIO_BASE) = (reg_value & ~ mask) | (mask); + reg_value = GPIO_REG_GPFEN0(GPIO_BASE); + GPIO_REG_GPFEN0(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPAREN1(GPIO_BASE); + GPIO_REG_GPAREN1(GPIO_BASE) = (reg_value & ~ mask) | (mask); + reg_value = GPIO_REG_GPFEN1(GPIO_BASE); + GPIO_REG_GPFEN1(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + break; + case PIN_IRQ_MODE_HIGH_LEVEL: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPHEN0(GPIO_BASE); + GPIO_REG_GPHEN0(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPHEN1(GPIO_BASE); + GPIO_REG_GPHEN1(GPIO_BASE) = (reg_value & ~ mask) | ( mask); + } + break; + case PIN_IRQ_MODE_LOW_LEVEL: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPLEN0(GPIO_BASE); + GPIO_REG_GPLEN0(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPLEN1(GPIO_BASE); + GPIO_REG_GPLEN1(GPIO_BASE) = (reg_value & ~ mask) | (mask); + } + break; + } return RT_EOK; } static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_int32_t pin) { + rt_uint8_t index; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + + _g_gpio_irq_tbl[index].irq_cb[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_arg[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_type[pin] = RT_NULL; + _g_gpio_irq_tbl[index].state[pin] = RT_NULL; + return RT_EOK; } rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) { + rt_uint8_t index; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + + if (enabled) + _g_gpio_irq_tbl[index].state[pin] = 1; + else + _g_gpio_irq_tbl[index].state[pin] = 0; + return RT_EOK; } @@ -132,12 +340,92 @@ static const struct rt_pin_ops ops = raspi_pin_detach_irq, raspi_pin_irq_enable, }; + +static void gpio_irq_handler(int irq, void *param) +{ + struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param; + rt_uint32_t pin; + rt_uint32_t value; + rt_uint32_t tmpvalue; + + if(irq == IRQ_GPIO0) + { + /* 0~27 */ + value = GPIO_REG_GPEDS0(GPIO_BASE); + value &= 0x0fffffff; + pin = 0; + GPIO_REG_GPEDS0(GPIO_BASE) = value; + } + else if(irq == IRQ_GPIO1) + { + /* 28-45 */ + tmpvalue = GPIO_REG_GPEDS0(GPIO_BASE); + tmpvalue &= (~0x0fffffff); + GPIO_REG_GPEDS0(GPIO_BASE) = tmpvalue; + + value = GPIO_REG_GPEDS1(GPIO_BASE); + value &= 0x3fff; + GPIO_REG_GPEDS1(GPIO_BASE) = value; + value = (value) | tmpvalue; + pin = 28; + } + else if (irq == IRQ_GPIO2) + { + /* 46-53 */ + value = GPIO_REG_GPEDS1(GPIO_BASE); + value &= (~0x3fff); + GPIO_REG_GPEDS1(GPIO_BASE) = value; + pin = 46; + } + + while (value) + { + if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL)) + { + if(irq_def->state[pin]) + { + irq_def->irq_cb[pin](irq_def->irq_arg[pin]); + } + } + pin++; + value = value >> 1; + } +} #endif int rt_hw_gpio_init(void) { #ifdef BSP_USING_PIN rt_device_pin_register("gpio", &ops, RT_NULL); + + //disable all intr + GPIO_REG_GPEDS0(GPIO_BASE) = 0xffffffff; + GPIO_REG_GPEDS1(GPIO_BASE) = 0xffffffff; + + GPIO_REG_GPREN0(GPIO_BASE) = 0x0; + GPIO_REG_GPREN1(GPIO_BASE) = 0x0; + + GPIO_REG_GPFEN0(GPIO_BASE) = 0x0; + GPIO_REG_GPFEN1(GPIO_BASE) = 0x0; + + GPIO_REG_GPHEN0(GPIO_BASE) = 0x0; + GPIO_REG_GPHEN1(GPIO_BASE) = 0x0; + + GPIO_REG_GPAREN0(GPIO_BASE) = 0x0; + GPIO_REG_GPAREN1(GPIO_BASE) = 0x0; + + GPIO_REG_GPAFEN0(GPIO_BASE) = 0x0; + GPIO_REG_GPAFEN0(GPIO_BASE) = 0x0; + + rt_hw_interrupt_install(IRQ_GPIO0, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq"); + rt_hw_interrupt_umask(IRQ_GPIO0); + + rt_hw_interrupt_install(IRQ_GPIO1, gpio_irq_handler, &_g_gpio_irq_tbl[1], "gpio1_irq"); + rt_hw_interrupt_umask(IRQ_GPIO1); + + rt_hw_interrupt_install(IRQ_GPIO2, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq"); + rt_hw_interrupt_umask(IRQ_GPIO2); + #endif return 0; diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_gpio.h b/bsp/raspberry-pi/raspi4-32/driver/drv_gpio.h index 2dde6990efa51d7fd9b6331116f20e307596efe3..44fa0464fd3c8d9e77c2d3c4f44c2138aa7a1f90 100644 --- a/bsp/raspberry-pi/raspi4-32/driver/drv_gpio.h +++ b/bsp/raspberry-pi/raspi4-32/driver/drv_gpio.h @@ -17,6 +17,14 @@ #include "board.h" #include "interrupt.h" +struct gpio_irq_def +{ + void *irq_arg[32]; + void (*irq_cb[32])(void *param); + rt_uint8_t irq_type[32]; + rt_uint8_t state[32]; +}; + #define GPIO_REG_GPFSEL0(BASE) HWREG32(BASE + 0x00) #define GPIO_REG_GPFSEL1(BASE) HWREG32(BASE + 0x04) #define GPIO_REG_GPFSEL2(BASE) HWREG32(BASE + 0x08) @@ -59,6 +67,10 @@ #define GPIO_REG_GPPUDCLK1(BASE) HWREG32(BASE + 0x9C) #define GPIO_REG_REV9(BASE) HWREG32(BASE + 0xA0) #define GPIO_REG_TEST(BASE) HWREG32(BASE + 0xA4) +#define GPIO_PUP_PDN_CNTRL_REG0(BASE) HWREG32(BASE + 0xE4) +#define GPIO_PUP_PDN_CNTRL_REG1(BASE) HWREG32(BASE + 0xE8) +#define GPIO_PUP_PDN_CNTRL_REG2(BASE) HWREG32(BASE + 0xEC) +#define GPIO_PUP_PDN_CNTRL_REG3(BASE) HWREG32(BASE + 0xF0) typedef enum { GPIO_PIN_0, @@ -115,6 +127,12 @@ typedef enum { ALT5 = 0b010 } GPIO_FUNC; +typedef enum { + RASPI_NO_RESISTOR = 0x00, + RASPI_PULL_UP = 0x01, + RASPI_PULL_DOWN = 0x10 +} GPIO_PUPD_FUNC; + void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode); int rt_hw_gpio_init(void); diff --git a/bsp/raspberry-pi/raspi4-32/driver/raspi4.h b/bsp/raspberry-pi/raspi4-32/driver/raspi4.h index 6c7fe3696b01c695d8f9b16d48862ae9a3c6bf37..bfdf7bfecc2d0c31cf137317bb644cd132176ed7 100644 --- a/bsp/raspberry-pi/raspi4-32/driver/raspi4.h +++ b/bsp/raspberry-pi/raspi4-32/driver/raspi4.h @@ -29,6 +29,11 @@ /* GPIO */ #define GPIO_BASE (PER_BASE + GPIO_BASE_OFFSET) +#define GPIO_IRQ_NUM (3) //40 pin mode +#define IRQ_GPIO0 (96 + 49) //bank0 (0 to 27) +#define IRQ_GPIO1 (96 + 50) //bank1 (28 to 45) +#define IRQ_GPIO2 (96 + 51) //bank2 (46 to 57) +#define IRQ_GPIO3 (96 + 52) //bank3 /* Timer (ARM side) */ #define ARM_TIMER_IRQ (64) diff --git a/bsp/raspberry-pi/raspi4-32/rtconfig.h b/bsp/raspberry-pi/raspi4-32/rtconfig.h index fa659a7e1d8858866e42271646de4b8a4a50523d..c073fa500379a26c441bb71d1cf860acd55926af 100644 --- a/bsp/raspberry-pi/raspi4-32/rtconfig.h +++ b/bsp/raspberry-pi/raspi4-32/rtconfig.h @@ -154,6 +154,12 @@ /* samples: kernel and components samples */ + +/* Privated Packages of RealThread */ + + +/* Network Utilities */ + #define BCM2711_SOC /* Hardware Drivers Config */ diff --git a/bsp/stm32/stm32l475-atk-pandora/rtconfig.py b/bsp/stm32/stm32l475-atk-pandora/rtconfig.py index 573c1f7492e78800782e5d1fc1d94419f7db295f..c29aca2346696abb66556214e17040ad3b493d4b 100644 --- a/bsp/stm32/stm32l475-atk-pandora/rtconfig.py +++ b/bsp/stm32/stm32l475-atk-pandora/rtconfig.py @@ -44,7 +44,7 @@ if PLATFORM == 'gcc': OBJCPY = PREFIX + 'objcopy' DEVICE = ' -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections' - CFLAGS = DEVICE + ' -Dgcc' + CFLAGS = DEVICE + ' -Dgcc -fstack-usage' AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rt-thread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds' diff --git a/tools/building.py b/tools/building.py index 2ddeb9669b8a4fda7d0a8dc1c860785f4a351d35..58939d79937bbbbe76c2d7cee601c194bcc90fc6 100644 --- a/tools/building.py +++ b/tools/building.py @@ -209,6 +209,11 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ dest = 'target', type = 'string', help = 'set target project: mdk/mdk4/mdk5/iar/vs/vsc/ua/cdk/ses/makefile/eclipse') + AddOption('--stackanalysis', + dest = 'stackanalysis', + action = 'store_true', + default = False, + help = 'thread stack static analysis') AddOption('--genconfig', dest = 'genconfig', action = 'store_true', @@ -363,6 +368,11 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ genconfig() exit(0) + if GetOption('stackanalysis'): + from stackanalysis import ThreadStackStaticAnalysis + ThreadStackStaticAnalysis(Env) + exit(0) + if env['PLATFORM'] != 'win32': AddOption('--menuconfig', dest = 'menuconfig', diff --git a/tools/stack.pl b/tools/stack.pl new file mode 100644 index 0000000000000000000000000000000000000000..fa297ae7e4bacff2d26f16ec9d4fada00f735322 --- /dev/null +++ b/tools/stack.pl @@ -0,0 +1,251 @@ +#!/usr/bin/perl -w +# avstack.pl: AVR stack checker +# Copyright (C) 2013 Daniel Beer +# +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all +# copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# +# Usage +# ----- +# +# This script requires that you compile your code with -fstack-usage. +# This results in GCC generating a .su file for each .o file. Once you +# have these, do: +# +# ./avstack.pl +# +# This will disassemble .o files to construct a call graph, and read +# frame size information from .su. The call graph is traced to find, for +# each function: +# +# - Call height: the maximum call height of any callee, plus 1 +# (defined to be 1 for any function which has no callees). +# +# - Inherited frame: the maximum *inherited* frame of any callee, plus +# the GCC-calculated frame size of the function in question. +# +# Using these two pieces of information, we calculate a cost (estimated +# peak stack usage) for calling the function. Functions are then listed +# on stdout in decreasing order of cost. +# +# Functions which are recursive are marked with an 'R' to the left of +# them. Their cost is calculated for a single level of recursion. +# +# The peak stack usage of your entire program can usually be estimated +# as the stack cost of "main", plus the maximum stack cost of any +# interrupt handler which might execute. + +use strict; + +# Configuration: set these as appropriate for your architecture/project. + +my $objdump = "E:/RT_Thread_Env/tools/gnu_gcc/arm_gcc/mingw/bin/arm-none-eabi-objdump"; +my $call_cost = 4; + +# First, we need to read all object and corresponding .su files. We're +# gathering a mapping of functions to callees and functions to frame +# sizes. We're just parsing at this stage -- callee name resolution +# comes later. + +my %frame_size; # "func@file" -> size +my %call_graph; # "func@file" -> {callees} +my %addresses; # "addr@file" -> "func@file" + +my %global_name; # "func" -> "func@file" +my %ambiguous; # "func" -> 1 + +foreach (@ARGV) { + # Disassemble this object file to obtain a callees. Sources in the + # call graph are named "func@file". Targets in the call graph are + # named either "offset@file" or "funcname". We also keep a list of + # the addresses and names of each function we encounter. + my $objfile = $_; + my $source; + + open(DISASSEMBLY, "$objdump -dr $objfile|") || + die "Can't disassemble $objfile"; + while () { + chomp; + + if (/^([0-9a-fA-F]+) <(.*)>:/) { + my $a = $1; + my $name = $2; + + $source = "$name\@$objfile"; + $call_graph{$source} = {}; + $ambiguous{$name} = 1 if defined($global_name{$name}); + $global_name{$name} = "$name\@$objfile"; + + $a =~ s/^0*//; + $addresses{"$a\@$objfile"} = "$name\@$objfile"; + } + + if (/: R_[A-Za-z0-9_]+_CALL[ \t]+(.*)/) { + my $t = $1; + + if ($t eq ".text") { + $t = "\@$objfile"; + } elsif ($t =~ /^\.text\+0x(.*)$/) { + $t = "$1\@$objfile"; + } + + $call_graph{$source}->{$t} = 1; + } + } + close(DISASSEMBLY); + + # Extract frame sizes from the corresponding .su file. + if ($objfile =~ /^(.*).o$/) { + my $sufile = "$1.su"; + + open(SUFILE, "<$sufile") || die "Can't open $sufile"; + while () { + $frame_size{"$1\@$objfile"} = $2 + $call_cost + if /^.*:([^\t ]+)[ \t]+([0-9]+)/; + } + close(SUFILE); + } +} + +# In this step, we enumerate each list of callees in the call graph and +# try to resolve the symbols. We omit ones we can't resolve, but keep a +# set of them anyway. + +my %unresolved; + +foreach (keys %call_graph) { + my $from = $_; + my $callees = $call_graph{$from}; + my %resolved; + + foreach (keys %$callees) { + my $t = $_; + + if (defined($addresses{$t})) { + $resolved{$addresses{$t}} = 1; + } elsif (defined($global_name{$t})) { + $resolved{$global_name{$t}} = 1; + warn "Ambiguous resolution: $t" if defined ($ambiguous{$t}); + } elsif (defined($call_graph{$t})) { + $resolved{$t} = 1; + } else { + $unresolved{$t} = 1; + } + } + + $call_graph{$from} = \%resolved; +} + +# Create fake edges and nodes to account for dynamic behaviour. +$call_graph{"INTERRUPT"} = {}; + +foreach (keys %call_graph) { + $call_graph{"INTERRUPT"}->{$_} = 1 if /Handler/; +} + +# Trace the call graph and calculate, for each function: +# +# - inherited frames: maximum inherited frame of callees, plus own +# frame size. +# - height: maximum height of callees, plus one. +# - recursion: is the function called recursively (including indirect +# recursion)? + +my %has_caller; +my %visited; +my %total_cost; +my %call_depth; + +sub trace { + my $f = shift; + + if ($visited{$f}) { + $visited{$f} = "R" if $visited{$f} eq "?"; + return; + } + + $visited{$f} = "?"; + + my $max_depth = 0; + my $max_frame = 0; + + my $targets = $call_graph{$f} || die "Unknown function: $f"; + if (defined($targets)) { + foreach (keys %$targets) { + my $t = $_; + + $has_caller{$t} = 1; + trace($t); + + my $is = $total_cost{$t}; + my $d = $call_depth{$t}; + + $max_frame = $is if $is > $max_frame; + $max_depth = $d if $d > $max_depth; + } + } + + $call_depth{$f} = $max_depth + 1; + $total_cost{$f} = $max_frame + ($frame_size{$f} || 0); + $visited{$f} = " " if $visited{$f} eq "?"; +} + +foreach (keys %call_graph) { trace $_; } + +# Now, print results in a nice table. +printf " %-30s %8s %8s %8s\n", + "Func", "Cost", "Frame", "Height"; +print "------------------------------------"; +print "------------------------------------\n"; + +my $max_iv = 0; +my $main = 0; + +foreach (sort { $total_cost{$b} <=> $total_cost{$a} } keys %visited) { + my $name = $_; + + if (/^(.*)@(.*)$/) { + $name = $1 unless $ambiguous{$name}; + } + + my $tag = $visited{$_}; + my $cost = $total_cost{$_}; + + $name = $_ if $ambiguous{$name}; + $tag = ">" unless $has_caller{$_}; + + if (/^__vector_/) { + $max_iv = $cost if $cost > $max_iv; + } elsif (/^main@/) { + $main = $cost; + } + + if ($ambiguous{$name}) { $name = $_; } + + printf "%s %-30s %8d %8d %8d\n", $tag, $name, $cost, + $frame_size{$_} || 0, $call_depth{$_}; +} + +print "\n"; + +print "Peak execution estimate (main + worst-case IV):\n"; +printf " main = %d, worst IV = %d, total = %d\n", + $total_cost{$global_name{"main"}}, + $total_cost{"INTERRUPT"}, + $total_cost{$global_name{"main"}} + $total_cost{"INTERRUPT"}; + +print "\n"; + +print "The following functions were not resolved:\n"; +foreach (keys %unresolved) { print " $_\n"; } \ No newline at end of file diff --git a/tools/stackanalysis.py b/tools/stackanalysis.py new file mode 100644 index 0000000000000000000000000000000000000000..6f33d52ce891f7670a9b35884c9bf7d961dc339e --- /dev/null +++ b/tools/stackanalysis.py @@ -0,0 +1,30 @@ +import os + +ofile = [] + +def searchofile(root): + global ofile + items = os.listdir(root) + for item in items: + path = os.path.join(root, item) + if os.path.isdir(path): + searchofile(path) + elif path.split('/')[-1].endswith('.o'): + if os.path.exists(path.replace('.o','.su')): + ofile.append(path) + else: + pass + + +def ThreadStackStaticAnalysis(env): + print('Start thread stack static analysis...') + + global ofile + file_dir = env['BSP_ROOT']+'/build' + searchofile(file_dir) + cmd = 'perl ' + env['RTT_ROOT'].replace(env['BSP_ROOT'],'.') + '/tools/stack.pl ' + ' '.join(ofile) + os.system(cmd) + + print('\n\ncmd:\n' + cmd) + print('\nThread stack static analysis done!') + return