mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-23 15:27:29 +08:00
fix(bsp/gd32/arm): 修复gd32硬件i2c驱动
- 硬件i2c主机接收驱动采用方案B,但不支持接收小于3字节,现修复该问题 - 增加方案A。
This commit is contained in:
@@ -1440,22 +1440,16 @@ CONFIG_BSP_USING_UART0=y
|
||||
# CONFIG_BSP_USING_UART3 is not set
|
||||
# CONFIG_BSP_USING_UART4 is not set
|
||||
# CONFIG_BSP_USING_UART5 is not set
|
||||
CONFIG_BSP_USING_HARD_I2C=y
|
||||
CONFIG_BSP_USING_RECEIVING_A=y
|
||||
# CONFIG_BSP_USING_RECEIVING_B is not set
|
||||
CONFIG_BSP_USING_HARD_I2C0=y
|
||||
# CONFIG_BSP_USING_HARD_I2C1 is not set
|
||||
# CONFIG_BSP_USING_HARD_I2C2 is not set
|
||||
# CONFIG_BSP_USING_SPI is not set
|
||||
# CONFIG_BSP_USING_ADC is not set
|
||||
# CONFIG_BSP_USING_HWTIMER is not set
|
||||
CONFIG_BSP_USING_PWM=y
|
||||
CONFIG_BSP_USING_PWM0=y
|
||||
CONFIG_BSP_USING_PWM1=y
|
||||
CONFIG_BSP_USING_PWM2=y
|
||||
CONFIG_BSP_USING_PWM3=y
|
||||
CONFIG_BSP_USING_PWM4=y
|
||||
CONFIG_BSP_USING_PWM7=y
|
||||
CONFIG_BSP_USING_PWM8=y
|
||||
CONFIG_BSP_USING_PWM9=y
|
||||
CONFIG_BSP_USING_PWM10=y
|
||||
CONFIG_BSP_USING_PWM11=y
|
||||
CONFIG_BSP_USING_PWM12=y
|
||||
CONFIG_BSP_USING_PWM13=y
|
||||
# CONFIG_BSP_USING_PWM is not set
|
||||
# CONFIG_BSP_USING_ONCHIP_RTC is not set
|
||||
# CONFIG_BSP_USING_WDT is not set
|
||||
# CONFIG_BSP_USING_SDIO is not set
|
||||
|
||||
@@ -232,6 +232,35 @@ menu "On-chip Peripheral Drivers"
|
||||
default 32
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_HARD_I2C
|
||||
bool "Enable I2C"
|
||||
select RT_USING_I2C
|
||||
default n
|
||||
if BSP_USING_HARD_I2C
|
||||
choice
|
||||
prompt "Select I2C Receiving Scheme"
|
||||
default BSP_USING_RECEIVING_A
|
||||
|
||||
config BSP_USING_RECEIVING_A
|
||||
bool "master receiving secheme A --- requires that the software be capable of responding quickly to the 12C event."
|
||||
|
||||
config BSP_USING_RECEIVING_B
|
||||
bool "master receiving secheme B --- don't requires that the software be capable of responding quickly to the 12C event."
|
||||
endchoice
|
||||
|
||||
config BSP_USING_HARD_I2C0
|
||||
bool "enable hard I2C0"
|
||||
default n
|
||||
|
||||
config BSP_USING_HARD_I2C1
|
||||
bool "enable hard I2C1"
|
||||
default n
|
||||
|
||||
config BSP_USING_HARD_I2C2
|
||||
bool "enable hard I2C2"
|
||||
default n
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_SPI
|
||||
bool "Enable SPI BUS"
|
||||
default n
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -338,9 +338,9 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>RT_USING_LIBC, HXTAL_VALUE=8000000U, RT_USING_ARMLIBC, USE_STDPERIPH_DRIVER, __RTTHREAD__, __CLK_TCK=RT_TICK_PER_SECOND, GD32F405, __STDC_LIMIT_MACROS</Define>
|
||||
<Define>RT_USING_LIBC, GD32F405, __RTTHREAD__, USE_STDPERIPH_DRIVER, __CLK_TCK=RT_TICK_PER_SECOND, RT_USING_ARMLIBC, __STDC_LIMIT_MACROS, HXTAL_VALUE=8000000U</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>packages\gd32-arm-cmsis-latest\GD32F4xx\GD\GD32F4xx\Include;packages\gd32-arm-cmsis-latest\GD32F4xx;.;..\..\..\..\components\drivers\include;..\..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\..\components\drivers\smp_call;..\..\..\..\components\libc\posix\io\poll;..\..\..\..\components\net\utest;applications;..\..\..\..\components\libc\compilers\common\extension;..\..\..\..\components\libc\posix\io\epoll;..\..\..\..\components\libc\compilers\common\include;..\..\..\..\components\libc\posix\ipc;..\..\..\..\components\drivers\include;packages\gd32-arm-series-latest\GD32F4xx\GD32F4xx_standard_peripheral\Include;..\..\..\..\components\drivers\phy;..\..\..\..\components\drivers\include;..\..\..\..\components\drivers\include;board;..\..\..\..\libcpu\arm\cortex-m4;..\..\..\..\libcpu\arm\common;..\..\..\..\include;..\..\..\..\components\drivers\include;..\..\..\..\components\drivers\include;..\..\..\..\components\finsh;..\..\..\..\components\drivers\include;..\libraries\gd32_drivers;..\..\..\..\components\drivers\include;..\..\..\..\components\libc\posix\io\eventfd</IncludePath>
|
||||
<IncludePath>applications;..\..\..\..\components\drivers\include;..\..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\..\components\drivers\include;..\..\..\..\components\libc\posix\ipc;..\..\..\..\components\libc\posix\io\poll;..\..\..\..\components\libc\posix\io\eventfd;board;..\..\..\..\components\drivers\include;..\..\..\..\components\drivers\smp_call;..\..\..\..\libcpu\arm\common;..\..\..\..\components\drivers\include;..\..\..\..\libcpu\arm\cortex-m4;packages\gd32-arm-cmsis-latest\GD32F4xx\GD\GD32F4xx\Include;..\..\..\..\components\libc\posix\io\epoll;..\libraries\gd32_drivers;..\..\..\..\components\libc\compilers\common\extension;..\..\..\..\components\net\utest;..\..\..\..\components\drivers\phy;..\..\..\..\include;packages\gd32-arm-cmsis-latest\GD32F4xx;.;..\..\..\..\components\drivers\include;packages\gd32-arm-series-latest\GD32F4xx\GD32F4xx_standard_peripheral\Include;..\..\..\..\components\drivers\include;..\..\..\..\components\drivers\include;..\..\..\..\components\libc\compilers\common\include;..\..\..\..\components\finsh;..\..\..\..\components\drivers\include</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -1406,6 +1406,11 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\libraries\gd32_drivers\drv_gpio.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>drv_hard_i2c.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\libraries\gd32_drivers\drv_hard_i2c.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>drv_hwtimer.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -1426,16 +1431,6 @@
|
||||
<Group>
|
||||
<GroupName>Finsh</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>msh_parse.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\components\finsh\msh_parse.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>shell.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\components\finsh\shell.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>msh.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -1446,6 +1441,16 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\components\finsh\cmd.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>shell.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\components\finsh\shell.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>msh_parse.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\components\finsh\msh_parse.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
@@ -2297,9 +2302,9 @@
|
||||
<GroupName>klibc</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>kstring.c</FileName>
|
||||
<FileName>kerrno.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\src\klibc\kstring.c</FilePath>
|
||||
<FilePath>..\..\..\..\src\klibc\kerrno.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rt_vsscanf.c</FileName>
|
||||
@@ -2307,9 +2312,9 @@
|
||||
<FilePath>..\..\..\..\src\klibc\rt_vsscanf.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>kerrno.c</FileName>
|
||||
<FileName>kstring.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\src\klibc\kerrno.c</FilePath>
|
||||
<FilePath>..\..\..\..\src\klibc\kstring.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>kstdio.c</FileName>
|
||||
@@ -2406,11 +2411,6 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>packages\gd32-arm-series-latest\GD32F4xx\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>gd32f4xx_timer.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>.\packages\gd32-arm-series-latest\GD32F4xx\GD32F4xx_standard_peripheral\Source\gd32f4xx_timer.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
|
||||
@@ -422,19 +422,9 @@
|
||||
#define BSP_USING_GPIO
|
||||
#define BSP_USING_UART
|
||||
#define BSP_USING_UART0
|
||||
#define BSP_USING_PWM
|
||||
#define BSP_USING_PWM0
|
||||
#define BSP_USING_PWM1
|
||||
#define BSP_USING_PWM2
|
||||
#define BSP_USING_PWM3
|
||||
#define BSP_USING_PWM4
|
||||
#define BSP_USING_PWM7
|
||||
#define BSP_USING_PWM8
|
||||
#define BSP_USING_PWM9
|
||||
#define BSP_USING_PWM10
|
||||
#define BSP_USING_PWM11
|
||||
#define BSP_USING_PWM12
|
||||
#define BSP_USING_PWM13
|
||||
#define BSP_USING_HARD_I2C
|
||||
#define BSP_USING_RECEIVING_A
|
||||
#define BSP_USING_HARD_I2C0
|
||||
#define BSP_USING_GD_DBG
|
||||
/* end of On-chip Peripheral Drivers */
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-12-20 BruceOu the first version
|
||||
* 2026-01-11 ShiHongchao Fix the I2C master receive mode B software
|
||||
* flow and add support for mode A
|
||||
*/
|
||||
|
||||
#include "drv_hard_i2c.h"
|
||||
@@ -112,8 +114,8 @@ static const struct gd32_i2c_bus gd_i2c_config[] = {
|
||||
|
||||
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 */
|
||||
GPIOB, GPIO_AF_4, GPIO_PIN_8, /* scl port, scl alternate, scl pin */
|
||||
GPIOB, GPIO_AF_4, GPIO_PIN_9, /* sda port, sda alternate, sda pin */
|
||||
|
||||
&i2c0,
|
||||
"hwi2c0",
|
||||
@@ -229,13 +231,52 @@ static void gd32_i2c_gpio_init(const struct gd32_i2c_bus *i2c)
|
||||
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 */
|
||||
|
||||
#ifdef BSP_USING_RECEIVING_A
|
||||
/*
|
||||
In single-byte reception, disable ACK because the master needs to send
|
||||
NACK after receiving the first byte,indicating no more data will be
|
||||
received, then immediately send the stop condition
|
||||
*/
|
||||
if(data_byte == 1)
|
||||
{
|
||||
/* disable acknowledge */
|
||||
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
|
||||
/* send a stop condition to I2C bus */
|
||||
i2c_stop_on_bus(i2c_periph);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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))
|
||||
{
|
||||
#ifdef BSP_USING_RECEIVING_A
|
||||
/*
|
||||
After receiving the second-to-last byte, ACK should be disabled
|
||||
and STOP should be set, to ensure that NACK is sent after receiving
|
||||
the last byte and the stop condition is transmitted
|
||||
*/
|
||||
if(2 == data_byte)
|
||||
{
|
||||
/* wait until BTC bit is set */
|
||||
while(!i2c_flag_get(i2c_periph, I2C_FLAG_RBNE));
|
||||
/* disable acknowledge */
|
||||
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
|
||||
/* send a stop condition to I2C bus */
|
||||
i2c_stop_on_bus(i2c_periph);
|
||||
}
|
||||
#elif defined(BSP_USING_RECEIVING_B)
|
||||
/*
|
||||
For 3-byte reception: Wait for byte transfer completion, then
|
||||
disable ACK so NACK is automatically sent after receiving the
|
||||
last byte
|
||||
For 2-byte reception: Wait for byte transfer completion, then
|
||||
send stop condition to ensure direct stop after receiving the
|
||||
last byte instead of sending ACK
|
||||
*/
|
||||
if(3 == data_byte)
|
||||
{
|
||||
/* wait until BTC bit is set */
|
||||
@@ -243,14 +284,16 @@ static uint8_t gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint8_t *p_buffer, rt_ui
|
||||
/* disable acknowledge */
|
||||
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
|
||||
}
|
||||
|
||||
if(2 == data_byte)
|
||||
else 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);
|
||||
}
|
||||
#else
|
||||
#error "Please select the receiving secheme."
|
||||
#endif
|
||||
/* wait until RBNE bit is set */
|
||||
if(i2c_flag_get(i2c_periph, I2C_FLAG_RBNE))
|
||||
{
|
||||
@@ -379,11 +422,18 @@ static rt_ssize_t gd32_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_
|
||||
{
|
||||
i2c_stop_on_bus(gd32_i2c->i2c_periph);
|
||||
}
|
||||
/* enable acknowledge */
|
||||
/* enable acknowledge */
|
||||
i2c_ack_config(gd32_i2c->i2c_periph, I2C_ACK_ENABLE);
|
||||
/* i2c master sends start signal only when the bus is idle */
|
||||
/* 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 */
|
||||
#ifdef BSP_USING_RECEIVING_B
|
||||
/* */
|
||||
if(msg->len == 2)
|
||||
{
|
||||
i2c_ackpos_config(gd32_i2c->i2c_periph, I2C_ACKPOS_NEXT);
|
||||
}
|
||||
#endif
|
||||
/* 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));
|
||||
@@ -391,14 +441,26 @@ static rt_ssize_t gd32_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_
|
||||
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 */
|
||||
#ifdef BSP_USING_RECEIVING_B
|
||||
if(msg->len <= 2)
|
||||
{
|
||||
i2c_ack_config(gd32_i2c->i2c_periph, I2C_ACK_DISABLE);
|
||||
}
|
||||
#endif
|
||||
/* address flag set means i2c slave sends ACK */
|
||||
i2c_flag_clear(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND);
|
||||
#ifdef BSP_USING_RECEIVING_B
|
||||
if(msg->len == 1)
|
||||
{
|
||||
i2c_stop_on_bus(gd32_i2c->i2c_periph);
|
||||
}
|
||||
#endif
|
||||
|
||||
}else {
|
||||
/* configure slave address */
|
||||
/* 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_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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user