diff --git a/bsp/gd32/arm/gd32h759i-eval/.config b/bsp/gd32/arm/gd32h759i-eval/.config index dba099e3b60..5d71fdfa9fe 100644 --- a/bsp/gd32/arm/gd32h759i-eval/.config +++ b/bsp/gd32/arm/gd32h759i-eval/.config @@ -104,11 +104,9 @@ # # CONFIG_RT_KLIBC_USING_USER_STRNLEN is not set # end of rt_strnlen options - -# CONFIG_RT_UTEST_TC_USING_KLIBC is not set # end of klibc options -CONFIG_RT_NAME_MAX=8 +CONFIG_RT_NAME_MAX=16 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_NANO is not set # CONFIG_RT_USING_SMART is not set @@ -1443,6 +1441,7 @@ CONFIG_BSP_USING_UART0=y # CONFIG_BSP_USING_UART1 is not set # CONFIG_BSP_USING_UART2 is not set # CONFIG_BSP_USING_UART3 is not set +# CONFIG_BSP_USING_I2C is not set # end of On-chip Peripheral Drivers # diff --git a/bsp/gd32/arm/gd32h759i-eval/board/Kconfig b/bsp/gd32/arm/gd32h759i-eval/board/Kconfig index 54a654ed6eb..f2c35205f59 100644 --- a/bsp/gd32/arm/gd32h759i-eval/board/Kconfig +++ b/bsp/gd32/arm/gd32h759i-eval/board/Kconfig @@ -69,8 +69,37 @@ menu "On-chip Peripheral Drivers" endif - source "$(BSP_DIR)/../libraries/gd32_drivers/Kconfig" + menuconfig BSP_USING_I2C + bool "Enable I2C" + default n + if BSP_USING_I2C + menuconfig BSP_USING_HARD_I2C + bool "Enable Hardware I2C" + default n + select RT_USING_I2C + if BSP_USING_HARD_I2C + config BSP_USING_HARD_I2C0 + bool "Enable I2C0 Hardware BUS" + default n + config BSP_USING_HARD_I2C1 + bool "Enable I2C1 Hardware BUS" + default n + config BSP_USING_HARD_I2C2 + bool "Enable I2C2 Hardware BUS" + default n + config BSP_USING_HARD_I2C3 + bool "Enable I2C3 Hardware BUS" + default n + config BSP_USING_HARD_I2C4 + bool "Enable I2C4 Hardware BUS" + default n + config BSP_USING_HARD_I2C5 + bool "Enable I2C5 Hardware BUS" + default n + endif + endif + source "$(BSP_DIR)/../libraries/gd32_drivers/Kconfig" endmenu menu "Board extended module Drivers" diff --git a/bsp/gd32/arm/gd32h759i-eval/project.uvoptx b/bsp/gd32/arm/gd32h759i-eval/project.uvoptx index 881a54bdf9e..af36f61c73b 100644 --- a/bsp/gd32/arm/gd32h759i-eval/project.uvoptx +++ b/bsp/gd32/arm/gd32h759i-eval/project.uvoptx @@ -117,31 +117,6 @@ BIN\CMSIS_AGDI.dll - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - DLGUARM - - - - 0 - CMSIS_AGDI - -X"Any" -UAny -O206 -S0 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(0BD12477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD24000000 -FC2000 -FN1 -FF0GD32H7xx_3840KB.FLM -FS08000000 -FL03C0000 -FP0($$Device:GD32H759IM$Flash\GD32H7xx_3840KB.FLM) - 0 UL2CM3 @@ -155,12 +130,12 @@ 0 0 - 1 + 0 0 0 0 0 - 1 + 0 0 0 0 @@ -215,7 +190,7 @@ - Compiler + at24cxx 0 0 0 @@ -227,14 +202,34 @@ 0 0 0 + packages\at24cxx-latest\at24cxx.c + at24cxx.c + 0 + 0 + + + + + Compiler + 0 + 0 + 0 + 0 + + 3 + 3 + 1 + 0 + 0 + 0 ..\..\..\..\components\libc\compilers\armlibc\syscall_mem.c syscall_mem.c 0 0 - 2 - 3 + 3 + 4 1 0 0 @@ -245,8 +240,8 @@ 0 - 2 - 4 + 3 + 5 1 0 0 @@ -257,8 +252,8 @@ 0 - 2 - 5 + 3 + 6 1 0 0 @@ -269,8 +264,8 @@ 0 - 2 - 6 + 3 + 7 1 0 0 @@ -281,8 +276,8 @@ 0 - 2 - 7 + 3 + 8 1 0 0 @@ -293,8 +288,8 @@ 0 - 2 - 8 + 3 + 9 1 0 0 @@ -305,8 +300,8 @@ 0 - 2 - 9 + 3 + 10 1 0 0 @@ -325,8 +320,8 @@ 0 0 - 3 - 10 + 4 + 11 1 0 0 @@ -337,8 +332,8 @@ 0 - 3 - 11 + 4 + 12 1 0 0 @@ -349,8 +344,8 @@ 0 - 3 - 12 + 4 + 13 1 0 0 @@ -361,8 +356,8 @@ 0 - 3 - 13 + 4 + 14 1 0 0 @@ -373,8 +368,20 @@ 0 - 3 - 14 + 4 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\components\drivers\i2c\dev_soft_i2c.c + dev_soft_i2c.c + 0 + 0 + + + 4 + 16 1 0 0 @@ -385,8 +392,8 @@ 0 - 3 - 15 + 4 + 17 1 0 0 @@ -397,8 +404,8 @@ 0 - 3 - 16 + 4 + 18 1 0 0 @@ -409,8 +416,8 @@ 0 - 3 - 17 + 4 + 19 1 0 0 @@ -421,8 +428,8 @@ 0 - 3 - 18 + 4 + 20 1 0 0 @@ -433,8 +440,8 @@ 0 - 3 - 19 + 4 + 21 1 0 0 @@ -445,8 +452,8 @@ 0 - 3 - 20 + 4 + 22 1 0 0 @@ -457,8 +464,8 @@ 0 - 3 - 21 + 4 + 23 1 0 0 @@ -469,8 +476,8 @@ 0 - 3 - 22 + 4 + 24 1 0 0 @@ -481,8 +488,8 @@ 0 - 3 - 23 + 4 + 25 1 0 0 @@ -493,8 +500,8 @@ 0 - 3 - 24 + 4 + 26 1 0 0 @@ -508,13 +515,13 @@ Drivers - 1 + 0 0 0 0 - 4 - 25 + 5 + 27 1 0 0 @@ -525,8 +532,8 @@ 0 - 4 - 26 + 5 + 28 1 0 0 @@ -537,8 +544,8 @@ 0 - 4 - 27 + 5 + 29 1 0 0 @@ -557,8 +564,8 @@ 0 0 - 5 - 28 + 6 + 30 1 0 0 @@ -569,8 +576,8 @@ 0 - 5 - 29 + 6 + 31 1 0 0 @@ -581,8 +588,8 @@ 0 - 5 - 30 + 6 + 32 1 0 0 @@ -593,8 +600,8 @@ 0 - 5 - 31 + 6 + 33 1 0 0 @@ -605,8 +612,8 @@ 0 - 5 - 32 + 6 + 34 1 0 0 @@ -625,56 +632,56 @@ 0 0 - 6 - 33 + 7 + 35 1 0 0 0 - ..\..\..\..\components\finsh\cmd.c - cmd.c + ..\..\..\..\components\finsh\msh_file.c + msh_file.c 0 0 - 6 - 34 + 7 + 36 1 0 0 0 - ..\..\..\..\components\finsh\msh_parse.c - msh_parse.c + ..\..\..\..\components\finsh\shell.c + shell.c 0 0 - 6 - 35 + 7 + 37 1 0 0 0 - ..\..\..\..\components\finsh\shell.c - shell.c + ..\..\..\..\components\finsh\cmd.c + cmd.c 0 0 - 6 - 36 + 7 + 38 1 0 0 0 - ..\..\..\..\components\finsh\msh_file.c - msh_file.c + ..\..\..\..\components\finsh\msh_parse.c + msh_parse.c 0 0 - 6 - 37 + 7 + 39 1 0 0 @@ -693,8 +700,8 @@ 0 0 - 7 - 38 + 8 + 40 1 0 0 @@ -705,8 +712,8 @@ 0 - 7 - 39 + 8 + 41 1 0 0 @@ -717,8 +724,8 @@ 0 - 7 - 40 + 8 + 42 1 0 0 @@ -729,8 +736,8 @@ 0 - 7 - 41 + 8 + 43 1 0 0 @@ -741,8 +748,8 @@ 0 - 7 - 42 + 8 + 44 1 0 0 @@ -753,8 +760,8 @@ 0 - 7 - 43 + 8 + 45 1 0 0 @@ -765,8 +772,8 @@ 0 - 7 - 44 + 8 + 46 1 0 0 @@ -777,8 +784,8 @@ 0 - 7 - 45 + 8 + 47 1 0 0 @@ -789,8 +796,8 @@ 0 - 7 - 46 + 8 + 48 1 0 0 @@ -801,8 +808,8 @@ 0 - 7 - 47 + 8 + 49 1 0 0 @@ -813,8 +820,8 @@ 0 - 7 - 48 + 8 + 50 1 0 0 @@ -825,8 +832,8 @@ 0 - 7 - 49 + 8 + 51 1 0 0 @@ -837,8 +844,8 @@ 0 - 7 - 50 + 8 + 52 1 0 0 @@ -849,8 +856,8 @@ 0 - 7 - 51 + 8 + 53 1 0 0 @@ -861,8 +868,8 @@ 0 - 7 - 52 + 8 + 54 1 0 0 @@ -881,62 +888,62 @@ 0 0 - 8 - 53 + 9 + 55 1 0 0 0 - ..\..\..\..\src\klibc\kstdio.c - kstdio.c + ..\..\..\..\src\klibc\kerrno.c + kerrno.c 0 0 - 8 - 54 + 9 + 56 1 0 0 0 - ..\..\..\..\src\klibc\rt_vsscanf.c - rt_vsscanf.c + ..\..\..\..\src\klibc\kstring.c + kstring.c 0 0 - 8 - 55 + 9 + 57 1 0 0 0 - ..\..\..\..\src\klibc\rt_vsnprintf_tiny.c - rt_vsnprintf_tiny.c + ..\..\..\..\src\klibc\kstdio.c + kstdio.c 0 0 - 8 - 56 + 9 + 58 1 0 0 0 - ..\..\..\..\src\klibc\kerrno.c - kerrno.c + ..\..\..\..\src\klibc\rt_vsnprintf_tiny.c + rt_vsnprintf_tiny.c 0 0 - 8 - 57 + 9 + 59 1 0 0 0 - ..\..\..\..\src\klibc\kstring.c - kstring.c + ..\..\..\..\src\klibc\rt_vsscanf.c + rt_vsscanf.c 0 0 @@ -949,8 +956,8 @@ 0 0 - 9 - 58 + 10 + 60 1 0 0 @@ -961,8 +968,8 @@ 0 - 9 - 59 + 10 + 61 1 0 0 @@ -973,8 +980,8 @@ 0 - 9 - 60 + 10 + 62 1 0 0 @@ -985,8 +992,8 @@ 0 - 9 - 61 + 10 + 63 2 0 0 @@ -997,8 +1004,8 @@ 0 - 9 - 62 + 10 + 64 1 0 0 @@ -1009,8 +1016,8 @@ 0 - 9 - 63 + 10 + 65 1 0 0 @@ -1029,8 +1036,8 @@ 0 0 - 10 - 64 + 11 + 66 2 0 0 @@ -1041,8 +1048,8 @@ 0 - 10 - 65 + 11 + 67 1 0 0 @@ -1053,8 +1060,20 @@ 0 - 10 - 66 + 11 + 68 + 1 + 0 + 0 + 0 + packages\gd32-arm-series-latest\GD32H7xx\GD32H7xx_standard_peripheral\Source\gd32h7xx_dma.c + gd32h7xx_dma.c + 0 + 0 + + + 11 + 69 1 0 0 @@ -1065,8 +1084,8 @@ 0 - 10 - 67 + 11 + 70 1 0 0 @@ -1077,8 +1096,8 @@ 0 - 10 - 68 + 11 + 71 1 0 0 @@ -1089,8 +1108,8 @@ 0 - 10 - 69 + 11 + 72 1 0 0 @@ -1101,8 +1120,8 @@ 0 - 10 - 70 + 11 + 73 1 0 0 @@ -1113,8 +1132,8 @@ 0 - 10 - 71 + 11 + 74 1 0 0 @@ -1125,8 +1144,8 @@ 0 - 10 - 72 + 11 + 75 1 0 0 @@ -1137,8 +1156,8 @@ 0 - 10 - 73 + 11 + 76 1 0 0 diff --git a/bsp/gd32/arm/gd32h759i-eval/project.uvprojx b/bsp/gd32/arm/gd32h759i-eval/project.uvprojx index 0b06d4e526c..b28b186d36e 100644 --- a/bsp/gd32/arm/gd32h759i-eval/project.uvprojx +++ b/bsp/gd32/arm/gd32h759i-eval/project.uvprojx @@ -138,7 +138,7 @@ 1 BIN\UL2CM3.DLL - "" () + @@ -338,9 +338,9 @@ 0 - GD32H7XX, RT_USING_ARMLIBC, USE_STDPERIPH_DRIVER, __CLK_TCK=RT_TICK_PER_SECOND, RT_USING_LIBC, __STDC_LIMIT_MACROS, __RTTHREAD__ + GD32H7XX, RT_USING_ARMLIBC, __CLK_TCK=RT_TICK_PER_SECOND, __RTTHREAD__, __STDC_LIMIT_MACROS, RT_USING_LIBC, USE_STDPERIPH_DRIVER - packages\gd32-arm-cmsis-latest\GD32H7xx\GD\GD32H7xx\Include;..\..\..\..\libcpu\arm\cortex-m7;..\..\..\..\libcpu\arm\common;..\..\..\..\components\drivers\include;..\..\..\..\components\libc\compilers\common\extension;.;..\..\..\..\components\libc\compilers\common\include;..\..\..\..\components\drivers\smp_call;packages\gd32-arm-cmsis-latest\GD32H7xx;..\..\..\..\components\drivers\include;..\..\..\..\components\finsh;..\..\..\..\components\dfs\dfs_v1\include;..\..\..\..\components\drivers\include;..\..\..\..\components\drivers\phy;..\..\..\..\include;..\..\..\..\components\dfs\dfs_v1\filesystems\devfs;board;..\libraries\gd32_drivers;..\..\..\..\components\libc\posix\io\eventfd;..\..\..\..\components\libc\posix\ipc;..\..\..\..\components\drivers\include;..\..\..\..\components\drivers\include;applications;..\..\..\..\components\libc\posix\io\poll;packages\gd32-arm-series-latest\GD32H7xx\GD32H7xx_standard_peripheral\Include;..\..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\..\components\libc\posix\io\epoll;..\..\..\..\components\drivers\include + ..\..\..\..\components\drivers\include;..\..\..\..\libcpu\arm\cortex-m7;packages\gd32-arm-cmsis-latest\GD32H7xx;packages\gd32-arm-cmsis-latest\GD32H7xx\GD\GD32H7xx\Include;..\..\..\..\components\drivers\include;..\..\..\..\components\libc\compilers\common\extension;..\..\..\..\components\finsh;..\..\..\..\components\drivers\smp_call;..\..\..\..\components\libc\posix\io\poll;..\..\..\..\components\libc\posix\io\epoll;..\..\..\..\components\libc\compilers\common\include;..\..\..\..\libcpu\arm\common;..\..\..\..\components\libc\posix\ipc;applications;..\..\..\..\components\libc\posix\io\eventfd;..\..\..\..\components\drivers\include;packages\at24cxx-latest;..\libraries\gd32_drivers;.;..\..\..\..\components\drivers\phy;..\..\..\..\components\drivers\include;board;..\..\..\..\components\drivers\include;..\..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\..\components\drivers\include;..\..\..\..\components\dfs\dfs_v1\include;..\..\..\..\components\dfs\dfs_v1\filesystems\devfs;..\..\..\..\include;packages\gd32-arm-series-latest\GD32H7xx\GD32H7xx_standard_peripheral\Include @@ -391,6 +391,16 @@ + + at24cxx + + + at24cxx.c + 1 + packages\at24cxx-latest\at24cxx.c + + + Compiler @@ -663,6 +673,62 @@ + + dev_soft_i2c.c + 1 + ..\..\..\..\components\drivers\i2c\dev_soft_i2c.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + __RT_IPC_SOURCE__ + + + + + + + completion_comm.c 1 @@ -1590,24 +1656,24 @@ Finsh - cmd.c + msh_file.c 1 - ..\..\..\..\components\finsh\cmd.c + ..\..\..\..\components\finsh\msh_file.c - msh_parse.c + shell.c 1 - ..\..\..\..\components\finsh\msh_parse.c + ..\..\..\..\components\finsh\shell.c - shell.c + cmd.c 1 - ..\..\..\..\components\finsh\shell.c + ..\..\..\..\components\finsh\cmd.c - msh_file.c + msh_parse.c 1 - ..\..\..\..\components\finsh\msh_file.c + ..\..\..\..\components\finsh\msh_parse.c msh.c @@ -2465,29 +2531,29 @@ klibc - kstdio.c + kerrno.c 1 - ..\..\..\..\src\klibc\kstdio.c + ..\..\..\..\src\klibc\kerrno.c - rt_vsscanf.c + kstring.c 1 - ..\..\..\..\src\klibc\rt_vsscanf.c + ..\..\..\..\src\klibc\kstring.c - rt_vsnprintf_tiny.c + kstdio.c 1 - ..\..\..\..\src\klibc\rt_vsnprintf_tiny.c + ..\..\..\..\src\klibc\kstdio.c - kerrno.c + rt_vsnprintf_tiny.c 1 - ..\..\..\..\src\klibc\kerrno.c + ..\..\..\..\src\klibc\rt_vsnprintf_tiny.c - kstring.c + rt_vsscanf.c 1 - ..\..\..\..\src\klibc\kstring.c + ..\..\..\..\src\klibc\rt_vsscanf.c @@ -2539,6 +2605,11 @@ 1 packages\gd32-arm-cmsis-latest\GD32H7xx\GD\GD32H7xx\Source\system_gd32h7xx.c + + gd32h7xx_dma.c + 1 + packages\gd32-arm-series-latest\GD32H7xx\GD32H7xx_standard_peripheral\Source\gd32h7xx_dma.c + gd32h7xx_exti.c 1 diff --git a/bsp/gd32/arm/gd32h759i-eval/rtconfig.h b/bsp/gd32/arm/gd32h759i-eval/rtconfig.h index c842aa85683..3a745212b4f 100644 --- a/bsp/gd32/arm/gd32h759i-eval/rtconfig.h +++ b/bsp/gd32/arm/gd32h759i-eval/rtconfig.h @@ -61,7 +61,7 @@ /* end of rt_strnlen options */ /* end of klibc options */ -#define RT_NAME_MAX 8 +#define RT_NAME_MAX 16 #define RT_CPUS_NR 1 #define RT_ALIGN_SIZE 8 #define RT_THREAD_PRIORITY_32 diff --git a/bsp/gd32/arm/libraries/gd32_drivers/SConscript b/bsp/gd32/arm/libraries/gd32_drivers/SConscript index dca1ac329f4..e11d8816ba4 100644 --- a/bsp/gd32/arm/libraries/gd32_drivers/SConscript +++ b/bsp/gd32/arm/libraries/gd32_drivers/SConscript @@ -26,8 +26,8 @@ if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']): # add i2c hard drivers. if GetDepend(['RT_USING_I2C']): - if GetDepend('BSP_USING_HW_I2C0') or GetDepend('BSP_USING_HW_I2C1'): - src += ['drv_hw_i2c.c'] + if GetDepend('BSP_USING_HARD_I2C0') or GetDepend('BSP_USING_HARD_I2C1') or GetDepend('BSP_USING_HARD_I2C2') or GetDepend('BSP_USING_HARD_I2C3') or GetDepend('BSP_USING_HARD_I2C4') or GetDepend('BSP_USING_HARD_I2C5'): + src += ['drv_hard_i2c.c'] # add spi drivers. if GetDepend('RT_USING_SPI'): diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_hard_i2c.c b/bsp/gd32/arm/libraries/gd32_drivers/drv_hard_i2c.c new file mode 100644 index 00000000000..725b306fde5 --- /dev/null +++ b/bsp/gd32/arm/libraries/gd32_drivers/drv_hard_i2c.c @@ -0,0 +1,562 @@ +/* + * Copyright (c) 2006-2025, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-12-20 BruceOu the first version + */ + +#include "drv_hard_i2c.h" + +#ifdef RT_USING_I2C + +#define LOG_TAG "drv.i2c" +#include + +#if !defined(BSP_USING_HARD_I2C0) && !defined(BSP_USING_HARD_I2C1) && !defined(BSP_USING_HARD_I2C2) && !defined(BSP_USING_HARD_I2C3) && !defined(BSP_USING_HARD_I2C4) && !defined(BSP_USING_HARD_I2C5) +#error "Please define at least one BSP_USING_I2Cx" +/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */ +#endif + +#if defined(BSP_USING_HARD_I2C0) +struct rt_i2c_bus_device i2c0; +#endif /* BSP_USING_I2C0 */ + +#if defined(BSP_USING_HARD_I2C1) +struct rt_i2c_bus_device i2c1; +#endif /* BSP_USING_I2C1 */ + +#if defined(BSP_USING_HARD_I2C2) +struct rt_i2c_bus_device i2c2; +#endif /* BSP_USING_I2C2 */ + +#if defined(BSP_USING_HARD_I2C3) +struct rt_i2c_bus_device i2c3; +#endif /* BSP_USING_I2C3 */ + +#if defined(BSP_USING_HARD_I2C4) +struct rt_i2c_bus_device i2c4; +#endif /* BSP_USING_I2C4 */ + +#if defined(BSP_USING_HARD_I2C5) +struct rt_i2c_bus_device i2c5; +#endif /* BSP_USING_I2C5 */ + +#if defined (SOC_SERIES_GD32F5xx) +#define i2c_flag_get_gd i2c_add_flag_get +#define I2C_FLAG_RBNE_GD I2C_ADD_FLAG_RBNE +#define i2c_data_receive_gd i2c_add_data_receive +#define I2C_STAT_GD I2C_ADD_STAT +#define I2C_STAT_TBE_GD I2C_ADD_STAT_TBE +#define i2c_data_transmit_gd i2c_add_data_transmit +#define I2C_STAT_TI_GD I2C_ADD_STAT_TI +#define i2c_address10_enable_gd i2c_add_address10_enable +#define i2c_address10_disable_gd i2c_add_address10_disable +#define i2c_master_addressing_gd i2c_add_master_addressing +#define I2C_MASTER_RECEIVE_GD I2C_ADD_MASTER_RECEIVE +#define i2c_transfer_byte_number_config_gd i2c_add_transfer_byte_number_config +#define i2c_start_on_bus_gd i2c_add_start_on_bus +#define I2C_MASTER_TRANSMIT_GD I2C_ADD_MASTER_TRANSMIT +#define I2C_FLAG_I2CBSY_GD I2C_ADD_FLAG_I2CBSY +#define I2C_FLAG_TC_GD I2C_ADD_FLAG_TC +#define I2C_FLAG_TI_GD I2C_ADD_FLAG_TI +#define i2c_stop_on_bus_gd i2c_add_stop_on_bus +#define I2C_FLAG_STPDET_GD I2C_ADD_FLAG_STPDET +#define i2c_timing_config_gd i2c_add_timing_config +#define i2c_master_clock_config_gd i2c_add_master_clock_config +#define i2c_enable_gd i2c_add_enable +#define i2c_flag_clear_gd i2c_add_flag_clear + +#else + +#define i2c_flag_get_gd i2c_flag_get +#define I2C_FLAG_RBNE_GD I2C_FLAG_RBNE +#define i2c_data_receive_gd i2c_data_receive +#define I2C_STAT_GD I2C_STAT +#define I2C_STAT_TBE_GD I2C_STAT_TBE +#define i2c_data_transmit_gd i2c_data_transmit +#define I2C_STAT_TI_GD I2C_STAT_TI +#define i2c_address10_enable_gd i2c_address10_enable +#define i2c_address10_disable_gd i2c_address10_disable +#define i2c_master_addressing_gd i2c_master_addressing +#define I2C_MASTER_RECEIVE_GD I2C_MASTER_RECEIVE +#define i2c_transfer_byte_number_config_gd i2c_transfer_byte_number_config +#define i2c_start_on_bus_gd i2c_start_on_bus +#define I2C_MASTER_TRANSMIT_GD I2C_MASTER_TRANSMIT +#define I2C_FLAG_I2CBSY_GD I2C_FLAG_I2CBSY +#define I2C_FLAG_TC_GD I2C_FLAG_TC +#define I2C_FLAG_TI_GD I2C_FLAG_TI +#define i2c_stop_on_bus_gd i2c_stop_on_bus +#define I2C_FLAG_STPDET_GD I2C_FLAG_STPDET +#define i2c_timing_config_gd i2c_timing_config +#define i2c_master_clock_config_gd i2c_master_clock_config +#define i2c_enable_gd i2c_enable +#define i2c_flag_clear_gd i2c_flag_clear + +#endif + +#if defined (SOC_SERIES_GD32F5xx) +#define IS_I2C_LEGACY(periph) ((periph) == I2C0 || (periph) == I2C1 || (periph) == I2C2) +#elif defined (SOC_SERIES_GD32F4xx) +#define IS_I2C_LEGACY(periph) (1) +#elif defined (SOC_SERIES_GD32H7xx) +#define IS_I2C_LEGACY(periph) (0) +#endif + +static const struct gd32_i2c_bus gd_i2c_config[] = { +#ifdef BSP_USING_HARD_I2C0 + { + I2C0, /* uart peripheral index */ + + RCU_I2C0, RCU_GPIOB, RCU_GPIOB, /* periph clock, scl gpio clock, sda gpio clock */ + + GPIOB, GPIO_AF_4, GPIO_PIN_6, /* scl port, scl alternate, scl pin */ + GPIOB, GPIO_AF_4, GPIO_PIN_7, /* sda port, sda alternate, sda pin */ + + &i2c0, + "hwi2c0", + }, +#endif + +#ifdef BSP_USING_HARD_I2C1 + { + I2C1, /* uart peripheral index */ + + RCU_I2C1, RCU_GPIOH, RCU_GPIOB, /* periph clock, scl gpio clock, sda gpio clock */ + + GPIOH, GPIO_AF_4, GPIO_PIN_4, /* scl port, scl alternate, scl pin */ + GPIOB, GPIO_AF_4, GPIO_PIN_11, /* sda port, sda alternate, sda pin */ + + &i2c1, + "hwi2c1", + }, +#endif + +#ifdef BSP_USING_HARD_I2C2 + { + I2C2, /* uart peripheral index */ + + RCU_I2C2, RCU_GPIOA, RCU_GPIOC, /* periph clock, scl gpio clock, sda gpio clock */ + + GPIOA, GPIO_AF_4, GPIO_PIN_8, /* scl port, scl alternate, scl pin */ + GPIOC, GPIO_AF_4, GPIO_PIN_9, /* sda port, sda alternate, sda pin */ + + &i2c2, + "hwi2c2", + }, +#endif + +#ifdef BSP_USING_HARD_I2C3 + { + I2C3, /* uart peripheral index */ + + RCU_I2C3, RCU_GPIOF, RCU_GPIOF, /* periph clock, scl gpio clock, sda gpio clock */ + + GPIOF, GPIO_AF_4, GPIO_PIN_14, /* scl port, scl alternate, scl pin */ + GPIOF, GPIO_AF_4, GPIO_PIN_15, /* sda port, sda alternate, sda pin */ + + &i2c3, + "hwi2c3", + }, +#endif +#ifdef BSP_USING_HARD_I2C4 + { + I2C4, /* uart peripheral index */ + + RCU_I2C4, RCU_GPIOG, RCU_GPIOG, /* periph clock, scl gpio clock, sda gpio clock */ + + GPIOG, GPIO_AF_6, GPIO_PIN_7, /* scl port, scl alternate, scl pin */ + GPIOG, GPIO_AF_6, GPIO_PIN_8, /* sda port, sda alternate, sda pin */ + + &i2c4, + "hwi2c4", + }, +#endif +#ifdef BSP_USING_HARD_I2C5 + { + I2C5, /* uart peripheral index */ + + RCU_I2C5, RCU_GPIOF, RCU_GPIOF, /* periph clock, scl gpio clock, sda gpio clock */ + + GPIOF, GPIO_AF_4, GPIO_PIN_11, /* scl port, scl alternate, scl pin */ + GPIOF, GPIO_AF_4, GPIO_PIN_12, /* sda port, sda alternate, sda pin */ + + &i2c5, + "hwi2c5", + } +#endif +}; + +/** + * @brief This function initializes the i2c pin. + * @param i2c + * @retval None + */ +static void gd32_i2c_gpio_init(const struct gd32_i2c_bus *i2c) +{ + /* enable I2C and GPIO clock */ + rcu_periph_clock_enable(i2c->scl_gpio_clk); + rcu_periph_clock_enable(i2c->sda_gpio_clk); + rcu_periph_clock_enable(i2c->per_clk); + + /* configure I2C_SCL as alternate function push-pull */ + gpio_af_set(i2c->scl_port, i2c->scl_af, i2c->scl_pin); + gpio_mode_set(i2c->scl_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, i2c->scl_pin); +#if defined (SOC_SERIES_GD32H7xx) + gpio_output_options_set(i2c->scl_port, GPIO_OTYPE_OD, GPIO_OSPEED_60MHZ, i2c->scl_pin); + /* configure I2C_SDA as alternate function push-pull */ + gpio_af_set(i2c->sda_port, i2c->sda_af, i2c->sda_pin); + gpio_mode_set(i2c->sda_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, i2c->sda_pin); + gpio_output_options_set(i2c->sda_port, GPIO_OTYPE_OD, GPIO_OSPEED_60MHZ, i2c->sda_pin); +#else + gpio_output_options_set(i2c->scl_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, i2c->scl_pin); + /* configure I2C_SDA as alternate function push-pull */ + gpio_af_set(i2c->sda_port, i2c->sda_af, i2c->sda_pin); + gpio_mode_set(i2c->sda_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, i2c->sda_pin); + gpio_output_options_set(i2c->sda_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, i2c->sda_pin); +#endif +} + +/** + * @brief read data. + * @param i2c_periph + * @param *p_buffer + * @param data_byte + * @retval None + */ +static uint8_t gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint8_t *p_buffer, rt_uint16_t data_byte) +{ + if (data_byte == 0) return 1; + /* while there is data to be read */ + + while(data_byte) + { +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32F4xx) + if(IS_I2C_LEGACY(i2c_periph)) + { + if(3 == data_byte) + { + /* wait until BTC bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)); + /* disable acknowledge */ + i2c_ack_config(i2c_periph, I2C_ACK_DISABLE); + } + + if(2 == data_byte) + { + /* wait until BTC bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(i2c_periph); + } + /* wait until RBNE bit is set */ + if(i2c_flag_get(i2c_periph, I2C_FLAG_RBNE)) + { + /* read a byte from the EEPROM */ + *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 */ + data_byte--; + } + }else +#endif + { + /* wait until the RBNE bit is set */ + while(!i2c_flag_get_gd(i2c_periph, I2C_FLAG_RBNE_GD)); + + /* read a byte */ + *p_buffer = i2c_data_receive_gd(i2c_periph); + /* point to the next location where the byte read will be saved */ + p_buffer++; + /* decrement the read bytes counter */ + data_byte--; + } + } + return 0; +} + +/** + * @brief write data. + * @param i2c_periph + * @param *p_buffer + * @param data_byte + * @retval None + */ +static uint8_t gd32_i2c_write(rt_uint32_t i2c_periph, uint8_t *p_buffer, uint16_t data_byte) +{ + if (data_byte == 0) return 1; + + while(data_byte) + { +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32F4xx) + if(IS_I2C_LEGACY(i2c_periph)) + { + /* data transmission */ + i2c_data_transmit(i2c_periph, *p_buffer); + /* point to the next byte to be written */ + p_buffer++; + /* decrement the write bytes counter */ + data_byte--; + /* wait until the TI bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)); + } + else +#endif + { +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32H7xx) + /* wait until the transmit data buffer is empty */ + I2C_STAT_GD(i2c_periph) |= I2C_STAT_TBE_GD; + while(!i2c_flag_get(i2c_periph, I2C_FLAG_TBE)); + + while(data_byte) + { + /* wait until the TI bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_TI_GD)); + /* data transmission */ + i2c_data_transmit(i2c_periph, *p_buffer); + /* point to the next byte to be written */ + p_buffer++; + /* decrement the write bytes counter */ + data_byte--; + } +#endif + } + } + + if(data_byte != 0) + { + return 1; + } + return 0; +} + +/** + * @brief + * @param + * @param + * @param + * @retval + */ + +static rt_ssize_t gd32_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) +{ + static struct rt_i2c_msg *msg; + + rt_uint32_t i,w_total_byte=0,r_total_byte=0; + rt_err_t ret = RT_ERROR; + + RT_ASSERT(bus != RT_NULL); + + struct gd32_i2c_bus *gd32_i2c = (struct gd32_i2c_bus *)bus->priv; + + for(i = 0; i < num; i++) + { + msg = &msgs[i]; + + if(msg->flags & RT_I2C_RD) + { + r_total_byte += msg->len; + }else{ + w_total_byte += msg->len; + } + } + + for(i = 0; i < num; i++) + { + msg = &msgs[i]; + if (!(msg->flags & RT_I2C_NO_START)) + { +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32F4xx) + if(IS_I2C_LEGACY(gd32_i2c->i2c_periph)) + { + + if(msg->flags & RT_I2C_RD) + { + if(i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY)) + { + i2c_stop_on_bus(gd32_i2c->i2c_periph); + } + /* enable acknowledge */ + i2c_ack_config(gd32_i2c->i2c_periph, I2C_ACK_ENABLE); + /* i2c master sends start signal only when the bus is idle */ + while(i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY)); + /* send the start signal */ + i2c_start_on_bus(gd32_i2c->i2c_periph); + /* i2c master sends START signal successfully */ + while(!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_SBSEND)); + + i2c_master_addressing(gd32_i2c->i2c_periph, msg->addr, I2C_RECEIVER); + + while(!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND)); + /* address flag set means i2c slave sends ACK */ + i2c_flag_clear(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND); + + }else { + /* configure slave address */ + while(i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY)); + //i2c_transfer_byte_number_config(gd32_i2c->i2c_periph, w_total_byte); + /* send a start condition to I2C bus */ + i2c_start_on_bus(gd32_i2c->i2c_periph); + while(!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_SBSEND)); + + i2c_master_addressing(gd32_i2c->i2c_periph, msg->addr, I2C_TRANSMITTER); + while(!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND)); + + i2c_flag_clear(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND); + } + }else +#endif + { +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32H7xx) + if(msg->flags & RT_I2C_ADDR_10BIT) + { + /* enable 10-bit addressing mode in master mode */ + i2c_address10_enable_gd(gd32_i2c->i2c_periph); + }else { + /* disable 10-bit addressing mode in master mode */ + i2c_address10_disable_gd(gd32_i2c->i2c_periph); + } + + if(msg->flags & RT_I2C_RD) + { + /* configure slave address */ + i2c_master_addressing_gd(gd32_i2c->i2c_periph, msg->addr, I2C_MASTER_RECEIVE_GD); + + i2c_transfer_byte_number_config_gd(gd32_i2c->i2c_periph, r_total_byte); + /* send a start condition to I2C bus */ + i2c_start_on_bus_gd(gd32_i2c->i2c_periph); + + }else { + /* configure slave address */ + i2c_master_addressing_gd(gd32_i2c->i2c_periph, msg->addr, I2C_MASTER_TRANSMIT_GD); + while(i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY_GD)); + i2c_transfer_byte_number_config_gd(gd32_i2c->i2c_periph, w_total_byte); + /* send a start condition to I2C bus */ + i2c_start_on_bus_gd(gd32_i2c->i2c_periph); + } +#endif + } + } + + if(msg->flags & RT_I2C_RD) + { + if(gd32_i2c_read(gd32_i2c->i2c_periph, msg->buf, msg->len) != 0) + { + LOG_E("i2c bus read failed,i2c bus stop!"); + goto out; + } + }else { + if(gd32_i2c_write(gd32_i2c->i2c_periph, msg->buf, msg->len) != 0) + { + LOG_E("i2c bus write failed,i2c bus stop!"); + goto out; + } + } +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32H7xx) + if(!IS_I2C_LEGACY(gd32_i2c->i2c_periph)) + { + if(r_total_byte != 0) + { + while(!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_TC_GD)); + } + } +#endif + + } + ret = i; + +out: +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32F4xx) + if(IS_I2C_LEGACY(gd32_i2c->i2c_periph)) + { + + if(!(msg->flags & RT_I2C_NO_STOP)) + { + if(msg->flags & RT_I2C_RD) + { + while((I2C_CTL0(gd32_i2c->i2c_periph) & I2C_CTL0_STOP)); + }else{ + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(gd32_i2c->i2c_periph); + /* wait until stop condition generate */ + while((I2C_CTL0(gd32_i2c->i2c_periph) & I2C_CTL0_STOP)); + /* clear the STPDET bit */ + } + } + }else +#endif + { +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32H7xx) + if(!(msg->flags & RT_I2C_NO_STOP)) + { + while(!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_TC_GD)); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus_gd(gd32_i2c->i2c_periph); + /* wait until stop condition generate */ + while(!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_STPDET_GD)); + /* clear the STPDET bit */ + i2c_flag_clear_gd(gd32_i2c->i2c_periph, I2C_FLAG_STPDET_GD); + } +#endif + } + return ret; +} + +static const struct rt_i2c_bus_device_ops i2c_ops = { + .master_xfer = gd32_i2c_master_xfer, + .slave_xfer = RT_NULL, + .i2c_bus_control = RT_NULL +}; + +/** + * @brief I2C initialization function + * @param None + * @retval RT_EOK indicates successful initialization. + */ +int rt_hw_i2c_init(void) +{ + rt_size_t obj_num = sizeof(gd_i2c_config) / sizeof(gd_i2c_config[0]); +// rt_err_t result; + + for(int i = 0; i < obj_num; i++) + { + + gd32_i2c_gpio_init(&gd_i2c_config[i]); + + /* configure I2C timing. I2C speed clock=400kHz*/ +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32F4xx) + if(IS_I2C_LEGACY(gd_i2c_config[i].i2c_periph)) + { + + i2c_clock_config(gd_i2c_config[i].i2c_periph, 100000, I2C_DTCY_2); + i2c_mode_addr_config(gd_i2c_config[i].i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0xa0); + i2c_enable(gd_i2c_config[i].i2c_periph); + i2c_ack_config(gd_i2c_config[i].i2c_periph, I2C_ACK_ENABLE); + }else +#endif + { +#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32H7xx) + i2c_timing_config_gd(gd_i2c_config[i].i2c_periph, 0x1, 0x7, 0); + i2c_master_clock_config_gd(gd_i2c_config[i].i2c_periph, 0x2D, 0x87); + + /* enable I2C1 */ + i2c_enable_gd(gd_i2c_config[i].i2c_periph); +#endif + } + + gd_i2c_config[i].i2c_bus->ops = &i2c_ops; + gd_i2c_config[i].i2c_bus->priv = (void *)&gd_i2c_config[i]; + + rt_i2c_bus_device_register(gd_i2c_config[i].i2c_bus, gd_i2c_config[i].device_name); + } + + return RT_EOK; +} + +INIT_BOARD_EXPORT(rt_hw_i2c_init); + +#endif /* RT_USING_I2C */ + diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_hard_i2c.h b/bsp/gd32/arm/libraries/gd32_drivers/drv_hard_i2c.h new file mode 100644 index 00000000000..1352a768ddc --- /dev/null +++ b/bsp/gd32/arm/libraries/gd32_drivers/drv_hard_i2c.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2006-2025, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-12-20 BruceOu the first version + */ + +#ifndef __DRV_I2C__ +#define __DRV_I2C__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* GD32 i2c driver */ +struct gd32_i2c_bus +{ + uint32_t i2c_periph; /* Todo: 3bits */ + + rcu_periph_enum per_clk; /* Todo: 5bits */ + rcu_periph_enum scl_gpio_clk; /* Todo: 5bits */ + rcu_periph_enum sda_gpio_clk; /* Todo: 5bits */ + + uint32_t scl_port; /* Todo: 4bits */ + uint16_t scl_af; /* Todo: 4bits */ + uint16_t scl_pin; /* Todo: 4bits */ + + uint32_t sda_port; /* Todo: 4bits */ + uint16_t sda_af; /* Todo: 4bits */ + uint16_t sda_pin; /* Todo: 4bits */ + + struct rt_i2c_bus_device *i2c_bus; + char *device_name; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __DRV_I2C__ */ + diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.c b/bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.c deleted file mode 100644 index 03269763edf..00000000000 --- a/bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (c) 2006-2025, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -#include "drv_hw_i2c.h" - - -#ifdef RT_USING_I2C - -#define LOG_TAG "drv.i2c" -#include - -static const struct gd32_i2c_config i2c_configs[] = -{ -#ifdef BSP_USING_HW_I2C0 - { - .i2c_periph = I2C0, .device_name = "i2c0", .periph_clk = RCU_I2C0, .i2c_clock_hz = BSP_HW_I2C0_CLOCK_SPEED, - .scl_clk = RCU_GPIOB, .scl_port = GPIOB, .scl_pin = GPIO_PIN_6, .scl_af = GPIO_AF_1, - .sda_clk = RCU_GPIOB, .sda_port = GPIOB, .sda_pin = GPIO_PIN_7, .sda_af = GPIO_AF_1, - .ev_irq_type = I2C0_EV_IRQn, .er_irq_type = I2C0_ER_IRQn, - }, -#endif -#ifdef BSP_USING_HW_I2C1 - { - .i2c_periph = I2C1, .device_name = "i2c1", .periph_clk = RCU_I2C1, .i2c_clock_hz = BSP_HW_I2C1_CLOCK_SPEED, - .scl_clk = RCU_GPIOB, .scl_port = GPIOB, .scl_pin = GPIO_PIN_10, .scl_af = GPIO_AF_1, - .sda_clk = RCU_GPIOB, .sda_port = GPIOB, .sda_pin = GPIO_PIN_11, .sda_af = GPIO_AF_1, - .ev_irq_type = I2C1_EV_IRQn, .er_irq_type = I2C1_ER_IRQn, - }, -#endif -}; - -static struct gd32_i2c i2c_objs[sizeof(i2c_configs) / sizeof(i2c_configs[0])]; - -#define I2C_GD32_ERR_BERR (1U << 0) /* Bus error */ -#define I2C_GD32_ERR_LARB (1U << 1) /* Arbitration lost */ -#define I2C_GD32_ERR_AERR (1U << 2) /* No ACK received */ -#define I2C_GD32_ERR_BUSY (1U << 4) /* I2C bus busy */ -static inline void i2c_enable_interrupts(uint32_t i2c_periph) -{ - i2c_interrupt_enable(i2c_periph, I2C_INT_ERR); - i2c_interrupt_enable(i2c_periph, I2C_INT_EV); - i2c_interrupt_enable(i2c_periph, I2C_INT_BUF); -} - -static inline void i2c_disable_interrupts(uint32_t i2c_periph) -{ - i2c_interrupt_disable(i2c_periph, I2C_INT_ERR); - i2c_interrupt_disable(i2c_periph, I2C_INT_EV); - i2c_interrupt_disable(i2c_periph, I2C_INT_BUF); -} - -static inline void i2c_log_error(struct gd32_i2c *i2c_dev) -{ - if (i2c_dev->errs & I2C_GD32_ERR_BERR) LOG_E("[%s] Bus error", i2c_dev->config->device_name); - if (i2c_dev->errs & I2C_GD32_ERR_LARB) LOG_E("[%s] Arbitration lost", i2c_dev->config->device_name); - if (i2c_dev->errs & I2C_GD32_ERR_AERR) LOG_E("[%s] No ACK received", i2c_dev->config->device_name); - if (i2c_dev->errs & I2C_GD32_ERR_BUSY) LOG_E("[%s] I2C bus is busy", i2c_dev->config->device_name); -} - -static inline void gd32_i2c_xfer_read(struct gd32_i2c *i2c_obj) -{ - const struct gd32_i2c_config *cfg = i2c_obj->config; - rt_uint8_t read_byte; - - i2c_obj->current->len--; - read_byte = I2C_DATA(cfg->i2c_periph); - *i2c_obj->current->buf = read_byte; - - LOG_D("[%s] < Read byte: 0x%02X", cfg->device_name, read_byte); - - i2c_obj->current->buf++; - - if ((i2c_obj->xfer_len > 0U) && (i2c_obj->current->len == 0U)) - { - i2c_obj->current++; - } -} - -static inline void gd32_i2c_xfer_write(struct gd32_i2c *i2c_obj) -{ - const struct gd32_i2c_config *cfg = i2c_obj->config; - - rt_uint8_t write_byte = *i2c_obj->current->buf; - LOG_D("[%s] > Write byte: 0x%02X", cfg->device_name, write_byte); - - i2c_obj->current->len--; - I2C_DATA(cfg->i2c_periph) = *i2c_obj->current->buf; - i2c_obj->current->buf++; - - if ((i2c_obj->xfer_len > 0U) && (i2c_obj->current->len == 0U)) - { - i2c_obj->current++; - } -} - -static void gd32_i2c_handle_tbe(struct gd32_i2c *i2c_obj) -{ - const struct gd32_i2c_config *cfg = i2c_obj->config; - LOG_D("[%s] TBE event: xfer_len=%d", cfg->device_name, i2c_obj->xfer_len); - - if (i2c_obj->xfer_len > 0U) - { - i2c_obj->xfer_len--; - if (i2c_obj->xfer_len == 0U) - { - LOG_D("[%s] Last byte to send, disabling BUFIE, waiting for BTC.", cfg->device_name); - I2C_CTL1(cfg->i2c_periph) &= ~I2C_CTL1_BUFIE; - } - gd32_i2c_xfer_write(i2c_obj); - } - else - { - LOG_D("[%s] TBE indicates all data sent. Generating STOP.", cfg->device_name); - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP; - rt_completion_done(&i2c_obj->sync_sem); - } -} - -static void gd32_i2c_handle_rbne(struct gd32_i2c *i2c_obj) -{ - const struct gd32_i2c_config *cfg = i2c_obj->config; - LOG_D("[%s] RBNE event: xfer_len=%d", cfg->device_name, i2c_obj->xfer_len); - - switch (i2c_obj->xfer_len) - { - case 0: - LOG_W("[%s] Unexpected RBNE, waking thread.", cfg->device_name); - rt_completion_done(&i2c_obj->sync_sem); - break; - case 1: - i2c_obj->xfer_len--; - gd32_i2c_xfer_read(i2c_obj); - LOG_D("[%s] RBNE: Last byte received, waking thread.", cfg->device_name); - rt_completion_done(&i2c_obj->sync_sem); - break; - case 2: - case 3: - LOG_D("[%s] RBNE: %d bytes left, disabling BUFIE, waiting for BTC.", cfg->device_name, i2c_obj->xfer_len); - I2C_CTL1(cfg->i2c_periph) &= ~I2C_CTL1_BUFIE; - break; - default: - i2c_obj->xfer_len--; - gd32_i2c_xfer_read(i2c_obj); - break; - } -} - -static void gd32_i2c_handle_btc(struct gd32_i2c *i2c_obj) -{ - const struct gd32_i2c_config *cfg = i2c_obj->config; - LOG_D("[%s] BTC event: xfer_len=%d, flags=0x%X", cfg->device_name, i2c_obj->xfer_len, i2c_obj->current->flags); - - if (i2c_obj->current->flags & RT_I2C_RD) - { - switch (i2c_obj->xfer_len) - { - case 2: - LOG_D("[%s] BTC: N=2, generating STOP.", cfg->device_name); - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP; - i2c_obj->xfer_len -= 2; - gd32_i2c_xfer_read(i2c_obj); - gd32_i2c_xfer_read(i2c_obj); - rt_completion_done(&i2c_obj->sync_sem); - break; - case 3: - LOG_D("[%s] BTC: N=3, clearing ACKEN for NACK.", cfg->device_name); - I2C_CTL0(cfg->i2c_periph) &= ~I2C_CTL0_ACKEN; - i2c_obj->xfer_len--; - gd32_i2c_xfer_read(i2c_obj); - break; - default: - LOG_W("[%s] Unexpected BTC in read mode, handling as RBNE.", cfg->device_name); - gd32_i2c_handle_rbne(i2c_obj); - break; - } - } - else - { - LOG_D("[%s] BTC in write mode, means last byte sent.", cfg->device_name); - gd32_i2c_handle_tbe(i2c_obj); - } -} - -static void gd32_i2c_handle_addsend(struct gd32_i2c *i2c_obj) -{ - const struct gd32_i2c_config *cfg = i2c_obj->config; - LOG_D("[%s] ADDSEND event: xfer_len=%d, flags=0x%X, is_restart=%d", cfg->device_name, i2c_obj->xfer_len, i2c_obj->current->flags, i2c_obj->is_restart); - - if ((i2c_obj->current->flags & RT_I2C_RD) && (i2c_obj->xfer_len <= 1U)) - { - LOG_D("[%s] ADDSEND: N<=1 read, clearing ACKEN.", cfg->device_name); - I2C_CTL0(cfg->i2c_periph) &= ~I2C_CTL0_ACKEN; - } - - (void)I2C_STAT0(cfg->i2c_periph); - (void)I2C_STAT1(cfg->i2c_periph); - - if (i2c_obj->is_restart) - { - i2c_obj->is_restart = RT_FALSE; - i2c_obj->current->flags |= RT_I2C_RD; - LOG_D("[%s] ADDSEND: 10-bit read restart. Generating RESTART.", cfg->device_name); - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_START; - return; - } - - if ((i2c_obj->current->flags & RT_I2C_RD) && (i2c_obj->xfer_len == 1U)) - { - LOG_D("[%s] ADDSEND: N=1 read, generating STOP.", cfg->device_name); - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP; - } -} - -static void gd32_i2c_event_handler(struct gd32_i2c *i2c_obj) -{ - const struct gd32_i2c_config *cfg; - uint32_t stat0; - - RT_ASSERT(i2c_obj != RT_NULL); - cfg = i2c_obj->config; - - stat0 = I2C_STAT0(cfg->i2c_periph); - LOG_D("[%s] EV_IRQ: STAT0=0x%08X", cfg->device_name, stat0); - - if (stat0 & I2C_STAT0_SBSEND) - { - uint8_t addr_byte; - if (i2c_obj->current->flags & RT_I2C_RD) - { - addr_byte = (i2c_obj->addr1 << 1) | 1; - } - else - { - addr_byte = (i2c_obj->addr1 << 1) | 0; - } - LOG_D("[%s] SBSEND: Sending address byte 0x%02X", cfg->device_name, addr_byte); - I2C_DATA(cfg->i2c_periph) = addr_byte; - } - else if (stat0 & I2C_STAT0_ADD10SEND) - { - LOG_D("[%s] ADD10SEND: Sending 2nd address byte 0x%02X", cfg->device_name, i2c_obj->addr2); - I2C_DATA(cfg->i2c_periph) = i2c_obj->addr2; - } - else if (stat0 & I2C_STAT0_ADDSEND) - { - gd32_i2c_handle_addsend(i2c_obj); - } - else if (stat0 & I2C_STAT0_BTC) - { - gd32_i2c_handle_btc(i2c_obj); - } - else if (stat0 & I2C_STAT0_RBNE) - { - gd32_i2c_handle_rbne(i2c_obj); - } - else if (stat0 & I2C_STAT0_TBE) - { - gd32_i2c_handle_tbe(i2c_obj); - } -} - -void gd32_i2c_error_handler(struct gd32_i2c *i2c_obj) -{ - const struct gd32_i2c_config *cfg; - uint32_t stat0; - - RT_ASSERT(i2c_obj != RT_NULL); - cfg = i2c_obj->config; - - stat0 = I2C_STAT0(cfg->i2c_periph); - LOG_E("[%s] ER_IRQ: STAT0=0x%08X", cfg->device_name, stat0); - - if (stat0 & I2C_STAT0_BERR) - { - I2C_STAT0(cfg->i2c_periph) &= ~I2C_STAT0_BERR; - i2c_obj->errs |= I2C_GD32_ERR_BERR; - } - - if (stat0 & I2C_STAT0_LOSTARB) - { - I2C_STAT0(cfg->i2c_periph) &= ~I2C_STAT0_LOSTARB; - i2c_obj->errs |= I2C_GD32_ERR_LARB; - } - - if (stat0 & I2C_STAT0_AERR) - { - I2C_STAT0(cfg->i2c_periph) &= ~I2C_STAT0_AERR; - i2c_obj->errs |= I2C_GD32_ERR_AERR; - } - - if (i2c_obj->errs != 0) - { - LOG_D("[%s] Error detected, sending STOP and waking thread.", cfg->device_name); - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP; - rt_completion_done(&i2c_obj->sync_sem); - } -} - -static rt_ssize_t gd32_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) -{ - struct gd32_i2c *i2c_dev; - const struct gd32_i2c_config *cfg; - rt_ssize_t i, itr; - rt_err_t result = RT_EOK; - - RT_ASSERT(bus != RT_NULL); - RT_ASSERT(msgs != RT_NULL); - RT_ASSERT(num > 0); - - i2c_dev = rt_container_of(bus, struct gd32_i2c, parent); - cfg = i2c_dev->config; - - LOG_D("[%s] master_xfer: num_msgs=%d", cfg->device_name, num); - - for (i = 0; i < num; i++) - { - if ((i < num - 1) && !(msgs[i].flags & RT_I2C_NO_STOP)) - { - LOG_E("[%s] Only the last message can have a STOP signal", cfg->device_name); - return -RT_EINVAL; - } - - if (msgs[i].len == 0 || msgs[i].buf == RT_NULL) - { - LOG_E("[%s] Invalid message buffer or length at index %d", cfg->device_name, i); - return -RT_EINVAL; - } - } - - rt_mutex_take(&i2c_dev->bus_mutex, RT_WAITING_FOREVER); - - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_I2CEN; - - for (i = 0; i < num; i = itr) - { - LOG_D("[%s] Processing msg segment starting at index %d", cfg->device_name, i); - i2c_dev->current = &msgs[i]; - i2c_dev->xfer_len = msgs[i].len; - rt_uint16_t current_addr = i2c_dev->current->addr; - - for (itr = i + 1; itr < num; itr++) - { - if ((msgs[itr].flags & RT_I2C_RD) != (i2c_dev->current->flags & RT_I2C_RD) || - msgs[itr].addr != current_addr) - { - break; - } - i2c_dev->xfer_len += msgs[itr].len; - } - LOG_D("[%s] Merged %d msgs. Total len=%d, addr=0x%X, flags=0x%X", - cfg->device_name, itr - i, i2c_dev->xfer_len, current_addr, i2c_dev->current->flags); - - LOG_D("[%s] Checking for bus busy...", cfg->device_name); - if (I2C_STAT1(cfg->i2c_periph) & I2C_STAT1_I2CBSY) - { - LOG_E("[%s] Bus is busy!", cfg->device_name); - i2c_dev->errs = I2C_GD32_ERR_BUSY; - result = -RT_EBUSY; - break; - } - - if (i2c_dev->current->flags & RT_I2C_ADDR_10BIT) - { - i2c_dev->addr1 = 0xF0 | ((current_addr >> 8) & 0x03); - i2c_dev->addr2 = current_addr & 0xFF; - LOG_D("[%s] 10-bit address: 0x%X -> addr1=0x%X, addr2=0x%X", cfg->device_name, current_addr, i2c_dev->addr1, i2c_dev->addr2); - } - else - { - i2c_dev->addr1 = current_addr & 0x7F; - } - - i2c_dev->errs = 0; - i2c_dev->is_restart = RT_FALSE; - rt_completion_init(&i2c_dev->sync_sem); - - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_ACKEN; - - if ((i2c_dev->current->flags & RT_I2C_RD) && (i2c_dev->current->flags & RT_I2C_ADDR_10BIT)) - { - LOG_D("[%s] Preparing for 10-bit read restart.", cfg->device_name); - i2c_dev->is_restart = RT_TRUE; - i2c_dev->current->flags &= ~RT_I2C_RD; - } - - if ((i2c_dev->current->flags & RT_I2C_RD) && (i2c_dev->xfer_len == 2)) - { - LOG_D("[%s] N=2 read, setting POAP.", cfg->device_name); - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_POAP; - } - - LOG_D("[%s] Generating START, enabling IRQs, waiting for completion...", cfg->device_name); - i2c_enable_interrupts(cfg->i2c_periph); - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_START; - - result = rt_completion_wait(&i2c_dev->sync_sem, bus->timeout); - - if (i2c_dev->is_restart == RT_TRUE) - { - i2c_dev->current->flags |= RT_I2C_RD; - } - - I2C_CTL0(cfg->i2c_periph) &= ~I2C_CTL0_POAP; - i2c_disable_interrupts(cfg->i2c_periph); - - if (result != RT_EOK) - { - LOG_E("[%s] I2C transaction timeout!", cfg->device_name); - result = -RT_ETIMEOUT; - I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP; - break; - } - - if (i2c_dev->errs != 0) - { - LOG_E("[%s] Hardware error detected by ISR.", cfg->device_name); - i2c_log_error(i2c_dev); - result = -RT_EIO; - break; - } - LOG_D("[%s] Transaction segment completed successfully.", cfg->device_name); - } - - if (result == RT_EOK) - { - if (!(msgs[num - 1].flags & RT_I2C_NO_STOP)) - { - LOG_D("[%s] Last message, Waiting STOP.", cfg->device_name); - rt_uint32_t timeout = 1000; - while (I2C_STAT1(cfg->i2c_periph) & I2C_STAT1_I2CBSY && timeout--) - { - rt_hw_us_delay(1); - } - } - else - { - LOG_D("[%s] Last message has NO_STOP flag, leaving bus active.", cfg->device_name); - } - } - - I2C_CTL0(cfg->i2c_periph) &= ~I2C_CTL0_I2CEN; - - rt_mutex_release(&i2c_dev->bus_mutex); - - LOG_D("[%s] master_xfer exiting with code: %d", cfg->device_name, (result == RT_EOK) ? i : result); - if (result == RT_EOK) - { - return i; - } - else - { - return result; - } -} - - -static struct gd32_i2c *_get_i2c_obj(uint32_t i2c_periph) -{ - for (size_t i = 0; i < sizeof(i2c_objs) / sizeof(i2c_objs[0]); i++) - { - if (i2c_objs[i].config->i2c_periph == i2c_periph) - { - return &i2c_objs[i]; - } - } - /* Should not happen in a correctly configured system. */ - LOG_E("Cannot find i2c_obj for periph: 0x%08X", i2c_periph); - return RT_NULL; -} - -#ifdef BSP_USING_HW_I2C0 -void I2C0_EV_IRQHandler(void) -{ - rt_interrupt_enter(); - - struct gd32_i2c *i2c_obj = _get_i2c_obj(I2C0); - if (i2c_obj) - { - gd32_i2c_event_handler(i2c_obj); - } - - rt_interrupt_leave(); -} - -void I2C0_ER_IRQHandler(void) -{ - rt_interrupt_enter(); - - struct gd32_i2c *i2c_obj = _get_i2c_obj(I2C0); - if (i2c_obj) - { - gd32_i2c_error_handler(i2c_obj); - } - - rt_interrupt_leave(); -} -#endif - - -#ifdef BSP_USING_HW_I2C1 -void I2C1_EV_IRQHandler(void) -{ - rt_interrupt_enter(); - - struct gd32_i2c *i2c_obj = _get_i2c_obj(I2C1); - if (i2c_obj) - { - gd32_i2c_event_handler(i2c_obj); - } - - rt_interrupt_leave(); -} - -void I2C1_ER_IRQHandler(void) -{ - rt_interrupt_enter(); - - struct gd32_i2c *i2c_obj = _get_i2c_obj(I2C1); - if (i2c_obj) - { - gd32_i2c_error_handler(i2c_obj); - } - - rt_interrupt_leave(); -} -#endif - - -static const struct rt_i2c_bus_device_ops gd32_i2c_ops = -{ - .master_xfer = gd32_i2c_master_xfer, - .slave_xfer = RT_NULL, - .i2c_bus_control = RT_NULL, -}; - -int rt_hw_i2c_init(void) -{ - rt_size_t obj_num = sizeof(i2c_objs) / sizeof(struct gd32_i2c); - rt_err_t result; - - for (int i = 0; i < obj_num; i++) - { - const struct gd32_i2c_config *config = &i2c_configs[i]; - struct gd32_i2c *i2c_obj = &i2c_objs[i]; - - LOG_D("Initializing %s...", config->device_name); - - i2c_obj->config = config; - i2c_obj->parent.ops = &gd32_i2c_ops; - i2c_obj->parent.timeout = RT_TICK_PER_SECOND; - - rcu_periph_clock_enable(config->scl_clk); - if (config->scl_clk != config->sda_clk) - { - rcu_periph_clock_enable(config->sda_clk); - } - rcu_periph_clock_enable(config->periph_clk); - - gpio_af_set(config->scl_port, config->scl_af, config->scl_pin); - gpio_mode_set(config->scl_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, config->scl_pin); - gpio_output_options_set(config->scl_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, config->scl_pin); - - gpio_af_set(config->sda_port, config->sda_af, config->sda_pin); - gpio_mode_set(config->sda_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, config->sda_pin); - gpio_output_options_set(config->sda_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, config->sda_pin); - - i2c_deinit(config->i2c_periph); - i2c_clock_config(config->i2c_periph, config->i2c_clock_hz, I2C_DTCY_2); - i2c_mode_addr_config(config->i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0); - i2c_enable(config->i2c_periph); - i2c_ack_config(config->i2c_periph, I2C_ACK_ENABLE); - - nvic_irq_enable(config->ev_irq_type, 2); - nvic_irq_enable(config->er_irq_type, 1); - - result = rt_i2c_bus_device_register(&i2c_obj->parent, config->device_name); - if (result != RT_EOK) - { - LOG_E("Failed to register i2c bus %s", config->device_name); - return result; - } - - rt_mutex_init(&i2c_obj->bus_mutex, - config->device_name, - RT_IPC_FLAG_FIFO); - - rt_completion_init(&i2c_obj->sync_sem); - - LOG_I("I2C bus %s registered successfully.", config->device_name); - } - return RT_EOK; -} -INIT_BOARD_EXPORT(rt_hw_i2c_init); - -#endif /* RT_USING_I2C */ - diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.h b/bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.h deleted file mode 100644 index 8cfe16e480e..00000000000 --- a/bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2006-2025, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -#ifndef __DRV_HW_I2C_H__ -#define __DRV_HW_I2C_H__ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* I2C hardware configuration */ -struct gd32_i2c_config -{ - rt_uint32_t i2c_periph; /* I2C peripheral base address */ - rcu_periph_enum periph_clk; /* I2C peripheral clock */ - - rcu_periph_enum scl_clk; /* SCL pin clock */ - rt_uint32_t scl_port; /* SCL pin port */ - rt_uint32_t scl_pin; /* SCL pin */ - rt_uint32_t scl_af; /* SCL pin alternate function */ - - rcu_periph_enum sda_clk; /* SDA pin clock */ - rt_uint32_t sda_port; /* SDA pin port */ - rt_uint32_t sda_pin; /* SDA pin */ - rt_uint32_t sda_af; /* SDA pin alternate function */ - - IRQn_Type ev_irq_type; /* Event IRQn */ - IRQn_Type er_irq_type; /* Error IRQn */ - - rt_uint32_t i2c_clock_hz; /* I2C clock speed in Hz, e.g., 100000 for 100kHz */ - - const char *device_name; /* Device name */ -}; - -/* I2C runtime context */ -struct gd32_i2c -{ - struct rt_i2c_bus_device parent; - const struct gd32_i2c_config *config; - - struct rt_mutex bus_mutex; - struct rt_completion sync_sem; - uint32_t dev_config; - uint16_t addr1; - uint16_t addr2; - uint32_t xfer_len; - struct rt_i2c_msg *current; - uint8_t errs; - rt_bool_t is_restart; -}; - -int rt_hw_i2c_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __DRV_HW_I2C_H__ */ - diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_soft_i2c.c b/bsp/gd32/arm/libraries/gd32_drivers/drv_soft_i2c.c deleted file mode 100644 index a6a27c355b9..00000000000 --- a/bsp/gd32/arm/libraries/gd32_drivers/drv_soft_i2c.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-12-20 BruceOu the first version - */ -#include "drv_soft_i2c.h" - -#ifdef RT_USING_I2C - -#define LOG_TAG "drv.i2c" -#include - -#if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) -#error "Please define at least one BSP_USING_I2Cx" -/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */ -#endif - -static const struct gd32_soft_i2c_config soft_i2c_config[] = -{ -#ifdef BSP_USING_I2C0 - I2C0_BUS_CONFIG, -#endif -#ifdef BSP_USING_I2C1 - I2C1_BUS_CONFIG, -#endif -#ifdef BSP_USING_I2C2 - I2C2_BUS_CONFIG, -#endif -#ifdef BSP_USING_I2C3 - I2C3_BUS_CONFIG, -#endif -}; - -static struct gd32_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])]; - -/** - * @brief This function initializes the i2c pin. - * @param i2c - * @retval None - */ -static void gd32_i2c_gpio_init(struct gd32_i2c *i2c) -{ - struct gd32_soft_i2c_config* cfg = (struct gd32_soft_i2c_config*)i2c->ops.data; - - rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD); - rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD); - - rt_pin_write(cfg->scl, PIN_HIGH); - rt_pin_write(cfg->sda, PIN_HIGH); -} - -static void gd32_i2c_pin_init(void) -{ - rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct gd32_i2c); - - for(rt_size_t i = 0; i < obj_num; i++) - { - gd32_i2c_gpio_init(&i2c_obj[i]); - } -} - -/** - * @brief This function sets the sda pin. - * @param data, state - * @retval None - */ -static void gd32_set_sda(void *data, rt_int32_t state) -{ - struct gd32_soft_i2c_config* cfg = (struct gd32_soft_i2c_config*)data; - if (state) - { - rt_pin_write(cfg->sda, PIN_HIGH); - } - else - { - rt_pin_write(cfg->sda, PIN_LOW); - } -} - -/** - * @brief This function sets the scl pin. - * @param data, state - * @retval None - */ -static void gd32_set_scl(void *data, rt_int32_t state) -{ - struct gd32_soft_i2c_config* cfg = (struct gd32_soft_i2c_config*)data; - if (state) - { - rt_pin_write(cfg->scl, PIN_HIGH); - } - else - { - rt_pin_write(cfg->scl, PIN_LOW); - } -} - -/** - * @brief This function gets the sda pin state. - * @param data - * @retval None - */ -static rt_int32_t gd32_get_sda(void *data) -{ - struct gd32_soft_i2c_config* cfg = (struct gd32_soft_i2c_config*)data; - return rt_pin_read(cfg->sda); -} - - -/** - * @brief This function gets the scl pin state. - * @param data - * @retval None - */ -static rt_int32_t gd32_get_scl(void *data) -{ - struct gd32_soft_i2c_config* cfg = (struct gd32_soft_i2c_config*)data; - return rt_pin_read(cfg->scl); -} - -/** - * @brief The time delay function. - * @param us - * @retval None - */ -static void gd32_udelay(rt_uint32_t us) -{ - int i = ( rcu_clock_freq_get(CK_SYS) / 4000000 * us); - while(i) - { - i--; - } -} - -static const struct rt_i2c_bit_ops gd32_bit_ops_default = -{ - .data = RT_NULL, - .pin_init = gd32_i2c_pin_init, - .set_sda = gd32_set_sda, - .set_scl = gd32_set_scl, - .get_sda = gd32_get_sda, - .get_scl = gd32_get_scl, - .udelay = gd32_udelay, - .delay_us = 1, - .timeout = 100, - .i2c_pin_init_flag = RT_FALSE -}; - -/** - * @brief if i2c is locked, this function will unlock it - * @param cfg - * @retval RT_EOK indicates successful unlock. - */ -static rt_err_t gd32_i2c_bus_unlock(const struct gd32_soft_i2c_config *cfg) -{ - rt_int32_t i = 0; - - if (PIN_LOW == rt_pin_read(cfg->sda)) - { - while (i++ < 9) - { - rt_pin_write(cfg->scl, PIN_HIGH); - gd32_udelay(100); - rt_pin_write(cfg->scl, PIN_LOW); - gd32_udelay(100); - } - } - if (PIN_LOW == rt_pin_read(cfg->sda)) - { - return -RT_ERROR; - } - - return RT_EOK; -} - -/** - * @brief I2C initialization function - * @param None - * @retval RT_EOK indicates successful initialization. - */ -int rt_hw_i2c_init(void) -{ - rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct gd32_i2c); - rt_err_t result; - - for (rt_size_t i = 0; i < obj_num; i++) - { - i2c_obj[i].ops = gd32_bit_ops_default; - i2c_obj[i].ops.data = (void*)&soft_i2c_config[i]; - i2c_obj[i].i2c_bus.priv = &i2c_obj[i].ops; - - result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c_bus, soft_i2c_config[i].bus_name); - - RT_ASSERT(result == RT_EOK); - - gd32_i2c_bus_unlock(&soft_i2c_config[i]); - - LOG_D("software simulation %s init done, pin scl: %d, pin sda %d", - soft_i2c_config[i].bus_name, - soft_i2c_config[i].scl, - soft_i2c_config[i].sda); - } - - return RT_EOK; -} -INIT_BOARD_EXPORT(rt_hw_i2c_init); - -#endif /* RT_USING_I2C */ diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_soft_i2c.h b/bsp/gd32/arm/libraries/gd32_drivers/drv_soft_i2c.h deleted file mode 100644 index f8ef15653c7..00000000000 --- a/bsp/gd32/arm/libraries/gd32_drivers/drv_soft_i2c.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-12-20 BruceOu the first version - */ - -#ifndef __DRV_I2C__ -#define __DRV_I2C__ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* gd32 config class */ -struct gd32_soft_i2c_config -{ - rt_uint8_t scl; - rt_uint8_t sda; - const char *bus_name; -}; - -/* gd32 i2c dirver class */ -struct gd32_i2c -{ - struct rt_i2c_bit_ops ops; - struct rt_i2c_bus_device i2c_bus; -}; - -#ifdef BSP_USING_I2C0 -#define I2C0_BUS_CONFIG \ - { \ - .scl = BSP_I2C0_SCL_PIN, \ - .sda = BSP_I2C0_SDA_PIN, \ - .bus_name = "i2c0", \ - } -#endif - -#ifdef BSP_USING_I2C1 -#define I2C1_BUS_CONFIG \ - { \ - .scl = BSP_I2C1_SCL_PIN, \ - .sda = BSP_I2C1_SDA_PIN, \ - .bus_name = "i2c1", \ - } -#endif - -#ifdef BSP_USING_I2C2 -#define I2C2_BUS_CONFIG \ - { \ - .scl = BSP_I2C2_SCL_PIN, \ - .sda = BSP_I2C2_SDA_PIN, \ - .bus_name = "i2c2", \ - } -#endif - -#ifdef BSP_USING_I2C3 -#define I2C3_BUS_CONFIG \ - { \ - .scl = BSP_I2C3_SCL_PIN, \ - .sda = BSP_I2C3_SDA_PIN, \ - .bus_name = "i2c3", \ - } -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __DRV_I2C__ */