Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,9 @@ hw_drv_onchip.i2c0:
kconfig:
- CONFIG_BSP_USING_I2C0=y
- CONFIG_BSP_I2C0_SCL_PIN=22
- CONFIG_BSP_I2C0_SDA_PIN=23
- CONFIG_BSP_I2C0_SDA_PIN=23
hw_drv_onchip.i2c1:
kconfig:
- CONFIG_BSP_USING_HW_I2C=y
- CONFIG_BSP_USING_HW_I2C1=y
- CONFIG_BSP_HW_I2C1_CLOCK_SPEED=400000
11 changes: 10 additions & 1 deletion bsp/gd32/arm/gd32e230-lckfb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,18 @@
| :--- | :---: | :--- |
| GPIO | 支持 | PAx, PBx... |
| UART | 支持 | USART0, USART1 |
| I2C | 支持 | I2C0, I2C1 硬件I2C |
| **扩展模块** | **支持情况** | **备注** |
| 暂无 | 暂不支持 | 暂不支持 |

### 补充说明

I2C 引脚分配:
- **I2C0**: SCL(PA9), SDA(PA10)
- **I2C1**: SCL(PB10), SDA(PB11)
默认速率400KHz,可以配置调整。


## 使用说明

使用说明分为如下两个章节:
Expand Down Expand Up @@ -95,7 +104,7 @@ pyocd flash -t gd32e230c8t6 rtthread.bin
4. 输入 `scons -j12` 编译。

## 注意事项
1. GD32E230资源受限,虽然通过调整参数极限运行msh,但是意义不大,建议关闭。
1. GD32E230资源受限,虽然通过调整参数可以运行msh,但是意义不大,建议关闭。
2. **GPIOA-13** 和 **GPIOA-14** 默认用于 SWD 调试下载功能,建议不要配置为其它功能,否则将可能导致无法正常下载和调试。

## 联系人信息
Expand Down
26 changes: 24 additions & 2 deletions bsp/gd32/arm/gd32e230-lckfb/board/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,35 @@ menu "On-chip Peripheral Drivers"
select RT_USING_I2C
default n
if BSP_USING_HW_I2C
config BSP_USING_I2C0
config BSP_USING_HW_I2C0
bool "Enable I2C0"
default y

config BSP_USING_I2C1
config BSP_HW_I2C0_CLOCK_SPEED
int "I2C0 Clock Speed (Hz)"
depends on BSP_USING_HW_I2C0
range 100000 1000000
default 400000
help
Set the I2C0 clock speed in Hz.
Standard mode: 100000 (100KHz)
Fast mode: 400000 (400KHz)
Fast mode plus: 1000000 (1MHz)

config BSP_USING_HW_I2C1
bool "Enable I2C1"
default n

config BSP_HW_I2C1_CLOCK_SPEED
int "I2C1 Clock Speed (Hz)"
depends on BSP_USING_HW_I2C1
range 100000 1000000
default 400000
help
Set the I2C1 clock speed in Hz.
Standard mode: 100000 (100KHz)
Fast mode: 400000 (400KHz)
Fast mode plus: 1000000 (1MHz)
endif
menuconfig BSP_USING_I2C0
bool "Enable I2C0 BUS (software simulation)"
Expand Down
2 changes: 1 addition & 1 deletion bsp/gd32/arm/gd32e230-lckfb/rtconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions bsp/gd32/arm/libraries/gd32_drivers/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ if GetDepend(['RT_USING_SERIAL']):
if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']):
if GetDepend('BSP_USING_I2C0') or GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3'):
src += ['drv_soft_i2c.c']

# 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']

# add spi drivers.
if GetDepend('RT_USING_SPI'):
Expand Down
186 changes: 186 additions & 0 deletions bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/*
* 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.hw_i2c"
#include <rtdbg.h>

#if !defined(BSP_USING_HW_I2C0) && !defined(BSP_USING_HW_I2C1)
#error "Please define at least one BSP_USING_HW_I2Cx in board.h"
#endif

static const struct gd32_i2c_config i2c_configs[] =
{
#ifdef BSP_USING_HW_I2C0
{
.i2c_periph = I2C0,
.periph_clk = RCU_I2C0,

.scl_clk = RCU_GPIOA,
.scl_port = GPIOA,
.scl_pin = GPIO_PIN_9,
.scl_af = GPIO_AF_4,
.sda_clk = RCU_GPIOA,
.sda_port = GPIOA,
.sda_pin = GPIO_PIN_10,
.sda_af = GPIO_AF_4,

.i2c_clock_hz = BSP_HW_I2C0_CLOCK_SPEED,
.device_name = "i2c0",
},
#endif
#ifdef BSP_USING_HW_I2C1
{
.i2c_periph = I2C1,
.periph_clk = RCU_I2C1,

.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,
.i2c_clock_hz = BSP_HW_I2C1_CLOCK_SPEED,
.device_name = "i2c1",
},
#endif
};

static struct gd32_i2c i2c_objs[sizeof(i2c_configs) / sizeof(i2c_configs[0])];

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 = rt_container_of(bus, struct gd32_i2c, parent);
const struct gd32_i2c_config *config = i2c_dev->config;
rt_uint32_t i2c_periph = config->i2c_periph;
rt_uint32_t i;
rt_err_t ret = RT_EOK;

while (i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY));

for (i = 0; i < num; i++)
{
struct rt_i2c_msg *msg = &msgs[i];
rt_uint16_t slave_addr = msg->addr;

i2c_start_on_bus(i2c_periph);
while (!i2c_flag_get(i2c_periph, I2C_FLAG_SBSEND));

if (msg->flags & RT_I2C_RD)
{
i2c_master_addressing(i2c_periph, slave_addr << 1, I2C_RECEIVER);
}
else
{
i2c_master_addressing(i2c_periph, slave_addr << 1, I2C_TRANSMITTER);
}

while (!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND));
i2c_flag_clear(i2c_periph, I2C_FLAG_ADDSEND);

if (msg->flags & RT_I2C_RD)
{
if (msg->len == 1)
{
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
}
else
{
i2c_ack_config(i2c_periph, I2C_ACK_ENABLE);
}

for (rt_uint32_t j = 0; j < msg->len; j++)
{
if (j == msg->len - 1)
{
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
}
while (!i2c_flag_get(i2c_periph, I2C_FLAG_RBNE));
msg->buf[j] = i2c_data_receive(i2c_periph);
}
}
else
{
for (rt_uint32_t j = 0; j < msg->len; j++)
{
while (!i2c_flag_get(i2c_periph, I2C_FLAG_TBE));
i2c_data_transmit(i2c_periph, msg->buf[j]);
}
while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC));
}

if (!(msg->flags & RT_I2C_NO_STOP))
{
i2c_stop_on_bus(i2c_periph);
while(i2c_flag_get(i2c_periph, I2C_FLAG_STPDET));
}
}

return (ret == RT_EOK) ? i : ret;
}


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++)
{
struct gd32_i2c *i2c_obj = &i2c_objs[i];
const struct gd32_i2c_config *config = &i2c_configs[i];

i2c_obj->config = config;

i2c_obj->i2c_clock_hz = config->i2c_clock_hz;

rcu_periph_clock_enable(config->periph_clk);
rcu_periph_clock_enable(config->scl_clk);
rcu_periph_clock_enable(config->sda_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, i2c_obj->i2c_clock_hz, I2C_DTCY_2);
i2c_mode_addr_config(config->i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x00);
i2c_enable(config->i2c_periph);
i2c_ack_config(config->i2c_periph, I2C_ACK_ENABLE);

i2c_obj->parent.ops = &gd32_i2c_ops;
result = rt_i2c_bus_device_register(&i2c_obj->parent, config->device_name);
RT_ASSERT(result == RT_EOK);

LOG_D("%s bus init success, clock %dHz.", config->device_name, i2c_obj->i2c_clock_hz);
}

return RT_EOK;
}

INIT_BOARD_EXPORT(rt_hw_i2c_init);

#endif

52 changes: 52 additions & 0 deletions bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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 <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <board.h>

#ifdef __cplusplus
extern "C" {
#endif

struct gd32_i2c_config
{
rt_uint32_t i2c_periph;
rcu_periph_enum periph_clk;

rcu_periph_enum scl_clk;
rt_uint32_t scl_port;
rt_uint32_t scl_pin;
rt_uint32_t scl_af;

rcu_periph_enum sda_clk;
rt_uint32_t sda_port;
rt_uint32_t sda_pin;
rt_uint32_t sda_af;

rt_uint32_t i2c_clock_hz; /* I2C clock frequency in Hz */
const char *device_name;
};

struct gd32_i2c
{
struct rt_i2c_bus_device parent;
const struct gd32_i2c_config *config;
rt_uint32_t i2c_clock_hz;
};

int rt_hw_i2c_init(void);

#ifdef __cplusplus
}
#endif

#endif /* __DRV_HW_I2C_H__ */